`

JUnit源码分析(一)——Command模式和Composite模式

阅读更多
    JUnit的源码相比于spring和hibernate来说比较简单,但麻雀虽小,五脏俱全,其中用到了比较多的设计模式。很多人已经在网上分享了他们对JUnit源码解读心得,我这篇小文谈不出什么新意,本来不打算写,可最近工作上暂时无事可做,那就写写吧,结合《设计模式》来看看。
    我读的是JUnit3.0的源码,目前JUnit已经发布到4.0版本了,尽管有比较大的改进,但基本的骨架不变,读3.0是为了抓住重点,省去对旁支末节的关注。我们来看看JUnit的核心代码,也就是Junit.framework包,除了4个辅助类(Assert,AssertFailedError,Protectable,TestFailure),剩下的就是我们需要重点关注的了。我先展示一张UML类图:

    我们先不去关注TestDecorator类(此处是Decorator模式,下篇文章再讲),看看Test接口,以及它的两个实现类TestCase和TestSuite。很明显,此处用到了Command模式,为什么要使用这个模式呢?让我们先来看看什么是Command模式。

Command模式

Command模式是行为型模式之一

1.意图:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。
2.适用场景:
1)抽象出待执行的动作以参数化对象,Command模式是回调函数的面向对象版本。回调函数,我想大家都明白,函数在某处注册,然后在稍后的某个时候被调用。
2)可以在不同的时刻指定、排列和执行请求。
3)支持修改日志,当系统崩溃时,这些修改可以被重做一遍。
4)通过Command模式,你可以通过一个公共接口调用所有的事务,并且也易于添加新的事务。


3。UML图:
   

4.效果:
1)命令模式将调用操作的对象与如何实现该操作的对象解耦。
2)将命令当成一个头等对象,它们可以像一般对象那样进行操纵和扩展
3)可以将多个命令复合成一个命令,与Composite模式结合使用
4)增加新的命令很容易,隔离对现有类的影响
5)可以与备忘录模式配合,实现撤销功能。

    在了解了Command模式之后,那我们来看JUnit的源码,Test接口就是命令的抽象接口,而TestCase和TestSuite是具体的命令
<!---->//抽象命令接口
package junit.framework;

/**
 * A Test can be run and collect its results.
 *
 * 
@see TestResult
 
*/
public interface Test {

    
/**
     * Counts the number of test cases that will be run by this test.
     
*/
    
public abstract int countTestCases();
    
/**
     * Runs a test and collects its result in a TestResult instance.
     
*/
    
public abstract void run(TestResult result);
}

//具体命令一

public abstract class TestCase extends Assert implements Test {
    
/**
     * the name of the test case
     
*/
    
private final String fName;
    
/**
   

//具体命令二

public class TestSuite implements Test {
     

由此带来的好处:
1.客户无需使用任何条件语句去判断测试的类型,可以用统一的方式调用测试和测试套件,解除了客户与具体测试子类的耦合
2.如果要增加新的TestCase也很容易,实现Test接口即可,不会影响到其他类。
3.很明显,TestSuite是通过组合多个TestCase的复合命令,这里使用到了Composite模式(组合)
4.尽管未实现redo和undo操作,但将来也很容易加入并实现。

    我们上面说到TestSuite组合了多个TestCase,应用到了Composite模式,那什么是Composite模式呢?具体来了解下。

Composite模式

composite模式是对象结构型模式之一。
1.意图:将对象组合成树形结构以表示“部分——整体”的层次结构。使得用户对单个对象和组合结构的使用具有一致性。

2.适用场景:
1)想表示对象的部分-整体层次
2)希望用户能够统一地使用组合结构和单个对象。具体到JUnit源码,我们是希望用户能够统一地方式使用TestCase和TestSuite

3.UML图:

      

图中单个对象就是树叶(Leaf),而组合结构就是Compoiste,它维护了一个Leaf的集合。而Component是一个抽象角色,给出了共有接口和默认行为,也就是JUnit源码中的Test接口。

4.效果:
1)定义了基本对象和组合对象的类层次结构,通过递归可以产生更复杂的组合对象
2)简化了客户代码,客户可以使用一致的方式对待单个对象和组合结构
3)添加新的组件变的很容易。但这个会带来一个问题,你无法限制组件中的组件,只能靠运行时的检查来施加必要的约束条件

    具体到JUnit源码,单个对象就是TestCase,而复合结构就是TestSuite,Test是抽象角色只有一个run方法。TestSuite维护了一个TestCase对象的集合fTests:

<!---->     private Vector fTests= new Vector(10); 
      
/**
     * Adds a test to the suite.
     
*/
    
public void addTest(Test test) {
        fTests.addElement(test);
    }
    /**
     * Runs the tests and collects their result in a TestResult.
     
*/
    
public void run(TestResult result) {
        
for (Enumeration e= tests(); e.hasMoreElements(); ) {
              
if (result.shouldStop() )
                  
break;
            Test test
= (Test)e.nextElement();
            test.run(result);
        }
    }

当执行run方法时遍历这个集合,调用里面每个TestCase对象的run()方法,从而执行测试。我们使用的时候仅仅需要把TestCase添加到集合内,然后用一致的方式(run方法)调用他们进行测试。

考虑使用Composite模式之后带来的好处:
1)JUnit可以统一地处理组合结构TestSuite和单个对象TestCase,避免了条件判断,并且可以递归产生更复杂的测试对象
2)很容易增加新的TestCase。


参考资料:《设计模式——可复用面向对象软件的基础》
          《JUnit设计模式分析》 刘兵
          JUnit源码和文档









    
分享到:
评论

相关推荐

    Junit设计模式分析——设计模式经典案例

    ### Junit设计模式分析——设计模式经典案例 #### 1. JUnit概述 **1.1 JUnit简介** JUnit是一个非常流行的Java单元测试框架,它最初由Erich Gamma和Kent Beck开发完成。作为XUnit测试体系架构的一种实现,JUnit...

    junit源码以及牵涉到的设计模式

    本文将深入探讨JUnit源码,并重点关注其中使用的设计模式,这些设计模式不仅提高了JUnit的可扩展性和维护性,还为开发人员提供了宝贵的编程思想。 #### 二、JUnit中的设计模式概述 ##### 1. Command 模式 在JUnit...

    Junit源码分析(圣思园)

    综上所述,通过对Junit的源码分析,我们可以更深入地理解其设计理念和实现细节,从而更好地利用这个测试框架来提升软件质量。阅读和学习Junit源码不仅能够帮助我们写出更健壮的测试用例,也能够提高我们的编程技能,...

    JUnit设计模式分析

    总之,JUnit的设计模式分析展示了如何将经典设计模式融入实际项目中,以达到简化代码、增强可维护性和提高代码复用性的目的。理解这些模式及其在JUnit中的应用,对于提升Java测试能力及软件开发实践具有重要意义。

    Junit设计模式分析

    《Junit设计模式分析》这本书深入探讨了如何在单元测试框架Junit中巧妙地应用设计模式,以提高代码的可测试性和可维护性。在软件开发过程中,设计模式是解决常见问题的最佳实践,它们能够帮助开发者创建灵活、可扩展...

    Junit设计模式分析(带源码)

    本资源"Junit设计模式分析(带源码)"旨在深入探讨JUnit在设计上的模式和最佳实践,通过源码分析帮助开发者更好地理解和应用这个工具。 1. 单元测试基础: 单元测试是对软件中的最小可测试单元进行检查,如函数、...

    Junit设计模式分析.docx

    Command 模式是 JUnit 中使用的设计模式之一。Command 模式的意图是将一个请求封装成一个对象,从而使你可用不同的请求对客户进行参数化,对请求进行排队或记录请求日志等。Command 模式告诉我们可以为一个操作生成...

    JUnit的框架设计及其使用的设计模式

    这个框架的设计基于一系列高效的设计模式,这些模式不仅提升了JUnit的灵活性,还使得开发者能够方便地扩展和定制测试功能。 首先,JUnit的核心设计理念是“简单易用”。它遵循了“最小化API”原则,提供了一套简洁...

    自动饮料机Junit测试(软件测试与质量保证实验).rar

    本实验“自动饮料机Junit测试”旨在帮助学生深入理解和应用单元测试,特别是在Java编程环境下。单元测试是一种针对程序代码最小可测试单元进行验证的方法,通常这个单元是函数或方法。Junit是Java领域广泛使用的单元...

    安卓Android源码——飞行历飞行模式AirPlus.zip

    "安卓Android源码——飞行历飞行模式AirPlus.zip"这个压缩包文件很可能是关于安卓系统中实现飞行模式的具体源代码,尤其是与AirPlus相关的部分。AirPlus可能是一个特定的模块或者功能,用于优化或扩展飞行模式的特性...

    自定义junit源码

    自定义JUnit源码是一个对Java开发人员非常有帮助的主题,特别是对于那些想要深入理解测试框架工作原理或希望根据自身需求定制测试工具的开发者。JUnit是一个广泛使用的单元测试框架,它简化了编写和运行针对Java代码...

    JUNIT设计模式分析PPT

    ### JUNIT设计模式分析 #### 1. JUnit概述 ##### 1.1 JUnit简介 JUnit是一个开源的Java测试框架,属于XUnit家族的一员。它由Erich Gamma和Kent Beck共同开发完成,旨在简化Java应用程序的单元测试过程。JUnit在...

    junit单元测试——浅浅笔记

    JUnit是Java编程语言中最常用的单元测试框架之一,它允许开发者编写可重复运行的测试用例,以确保代码的正确性和稳定性。以下是对JUnit单元测试框架的一些详细解释: 1. **JUnit简介**: JUnit是一个开源的、基于...

    软件单元测试——JUnit使用

    "软件单元测试——JUnit使用" 软件单元测试是软件开发过程中的一种测试方法,它是指对软件中的最小单元进行测试,以确保软件的可靠性和正确性。JUnit是一个流行的Java测试框架,广泛应用于软件单元测试中。 在本...

    Junit设计模式分析.pdf

    尽管标题提及了“Junit设计模式分析”,但实际内容并未涉及Junit的设计模式分析,而是侧重于JBoss 5的新特性介绍。因此,下面将围绕JBoss 5新特性进行深入解析。 ### JBoss 5 微容器(Microcontainer)介绍 #### ...

    junit 的源码jar包

    junit 的源码jar包 junit 的源码jar包 junit 的源码jar包

    Junit jar包以及 Junit 源码包

    Junit jar包以及 Junit 源码包

Global site tag (gtag.js) - Google Analytics