Junit代码分析之组合模式

发表于:2013-03-06来源:新浪博客作者:土司点击数: 标签:junit
在面向过程的编程中,类似于树形结构或者文件目录结构,一般使用递归的方式进行处理,而在面向过程中,对于这类问题抽象处理为组合模式。

  在面向过程的编程中,类似于树形结构或者文件目录结构,一般使用递归的方式进行处理,而在面向过程中,对于这类问题抽象处理为组合模式。

  组合模式(Composite Pattern)有时候又叫做部分-整体模式,它在处理树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。组合模式让你可以优化处理递归或分级数据结构。

  对于组合模式的角色也比较简单,我们试着对文件目录结构进行分析,在文件目录结构中至少有两种结构,一种是文件,一种是目录。对于这两个角色最大的区别就是,一个是叶子节点,一个是树枝结构。那么也可以把这两个对象抽象成一个接口类。这样分析后文件目录结构就有三个角色,即叶子(叶子组件),树枝 (组合组件),抽象结构(抽象构件接口)。下面对每个角色具体分析

  抽象构件角色(Component):它为组合中的对象声明接口,也可以为共有接口实现缺省行为。

  树叶构件角色(Leaf):在组合中表示叶节点对象——没有子节点,实现抽象构件角色声明的接口。

  树枝构件角色(Composite):在组合中表示分支节点对象——有子节点,实现抽象构件角色声明的接口;存储子部件。

  Client(客户端)

  –通过Component接口控制组合部件的对象

  各个角色之间关系如下:

 

  如图上图所示:一个Composite实例可以像一个简单的Leaf实例一样,可以把它传递给任何使用Component的方法或者对象,并且它表现的就像是一个Leaf一样。使用组合模式使得这个设计结构非常灵活。

  各个角色代码实现如下:

  抽象构件角色(Component):

  public interface Component

  {

  public void doSomething();

  }

  树叶构件角色(Leaf):

  public class Leaf implements Component

  {

  @Override

  public void doSomething()

  {

  System.out.println("执行方法");

  }

  }

  树枝构件角色(Composite):

  public class Composite implements Component

  {

  private List list = newArrayList();

  public void add(Component component)

  {

  list.add(component);

  }

  public void remove(Component component)

  {

  list.remove(component);

  }

  public List getAll()

  {

  return this.list;

  }

  public void doSomething()

  {

  for(Component component : list)

  {

  component.doSomething();

  }

  }

  }

  Client(客户端)

  public static void main(String[] args)

  {

  Component leaf1 = new Leaf();

  Component leaf2 = new Leaf();

  Composite comp1 = new Composite();

  comp1.add(leaf1);

  comp1.add(leaf2);

  Component leaf3 = new Leaf();

  Component leaf4 = new Leaf();

  Composite comp2 = new Composite();

  comp2.add(comp1);

  comp2.add(leaf3);

  comp2.add(leaf4);

  comp2.doSomething();

  }

  这样对组合模式就基本分析完成,继续接着看下在Junit组合模式是最样实现的呢?

  在Junit中有连个重要的概念,一个是TestCase一个是TestSuite;TestSuite是一个测试集合,一个TestSuite中可以包含一个或者多个TestSuite,当然也可以一个或者多个TestCase,而这两个对象都继承与Test接口。这样一分析,Test接口相当于组合模式中的抽象构件角色(Component),TestSuite相当于树枝构件角色(Composite),TestCase相当于树叶构件角色(Leaf)。接着我们对具体代码分析看看这块是否满足组合模式。

  Test接口类:

  public interface Test {

  public abstract int countTestCases();

  public abstract void run(TestResult result);

  }

  TestSuite实现:

  public int countTestCases() {

  int count= 0;

  for (Enumeration e= tests(); e.hasMoreElements(); ) {

  Test test= (Test)e.nextElement();

  count= count + test.countTestCases();

  }

  return count;

  }

  public void run(TestResult result) {

  for (Enumeration e= tests(); e.hasMoreElements(); ) {

  if (result.shouldStop() )

  break;

  Test test= (Test)e.nextElement();

  runTest(test, result);

  }

  }

  TestCase实现

  public int countTestCases() {

  return 1;

  }

  public void run(TestResult result) {

  result.run(this);

  }

  根据代码分析,Junit使用Composite模式后简化了JUnit的代码,JUnit可以统一处理组合结构TestSuite和单个对象TestCase。使JUnit开发变得简单容易,因为不需要区分部分和整体的区别,不需要写一些充斥着if else的选择语句。

  另外,通过对TestCase对象和TestSuite的类层次结构基本对象的定义,TestCase可以被组合成更复杂的组合对象TestSuite,而这些组合对象又可以被组合,这样不断地递归下去。在程序的代码中,任何使用基本对象的地方都可方便的使用组合对象,大大简化系统维护和开发。

原文转自:http://blog.sina.com.cn/s/blog_6e0d94750101653y.html