那我们就来看来如何解决这样的问题,首先,总结一下问题描述。在测试系统中,
- 测试报告具有相同的输出内容类型
- 测试报告需要有不同的输出形式(方式)
- 测试报告可能同时需要有两种或两种以上的输出形式
- 客户程序无需感知有多种输出方式存在
这时,往往有程序员会打开《设计模式》去寻找解决的方案,这真的是不好的方法,或者是找不到现成的模式,或者模式的误用就发生了。好在,这个确实是模式的一 种也许你可能找得到,但我还是不建议套用模式的方式解决问题。接下来我们看看通过自己分析来解决问题,和现存模式有什么区别。
根据问题描述4可以看得出,多种输出同时生效对于客户程序是透明的,也就是说,客户程序对于多种输出方式的调用和单个输出方式的调用具有相同的接口,另 外,多种输出方式是并列的关系,并不存在层次关系。我们可能根据客户程序调用形式想到,若我们将生成的一个或多个输出对象存储在一个容器内部,并且让这个 容器也具用输出内容接口。当对于这个容器调用输出内容接口的时候,就将这个操作依次传递给容器内所用对象。 哦~!原来是这样,就可以解决同时多种输出的问题,并且从客户角度看,只是对一个简单输出对象接口的调用,而完全不知,此时已是复杂对象了。
1package my.cnblog.output; 2import java.util.Vector; 3import java.util.Iterator; 4 5/*A Composite Outputter*/ 6 7public class OutputterContainer implements IOutputter { 8 9 private Vector<IOutputter> outputterVector = new Vector<IOutputter>(); 10 @Override 11 public boolean EndSuite() { 12 Iterator<IOutputter> it = outputterVector.iterator(); 13 while(it.hasNext()){ 14 boolean rs = it.next().EndSuite(); 15 if (rs == false) return false; 16 } 17 return true; 18 } 19 20 @Override 21 public boolean StartSuite(String suiteName) { 22 // the similar with the first function 23 return false; 24 } 25 26 @Override 27 public boolean TestResult(String result) { 28 // the similar with the first function 29 return false; 30 } 31 32 public void Add(IOutputter outputter){ 33 outputterVector.add(outputter); 34 } 35 36 public void Remove(IOutputter outputter){ 37 outputterVector.remove(outputter); 38 } 39 40} |
1package my.cnblog.output; 2 3/*Modified Outputter Factory*/ 4 5public class OutputterFactory { 6 IOutputter Create(String outputterList){ 7 OutputterContainer oc = new OutputterContainer(); 8 String[] list = outputterList.split(";"); 9 for (int i=0;i<list.length;i++){ 10 String outputter = list[i]; 11 if (outputter.equalsIgnoreCase("TXTOutputter")){ 12 oc.Add(new TXTOutputter()); 13 } 14 else if(outputter.equalsIgnoreCase("XMLOutputter")){ 15 /*oc.Add(new TXTOutputter());*/ 16 } 17 } 18 return null; 19 } 20 21} 22 |
代码为示意代码,真实代码还有更多细节需要处理
是的,就这么简单。我们看到系统正常的工作了。也许你会问,那它是什么模式呢?我前面提过它是一种模式来着的。是的。它应该是组合模式(Composite Pattern)的一种退化形式。那为什么说他是退化的形式呢?我们先来看一下,组合模式的定义:
合成(Composite)模型模式属于对象的结构模式[GOF95],有时又叫做部分-整体(Part-Whole)模式。合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。合成模式可以客户端将单纯元素与复合元素同等看待。
引用自《Java与模式》阎宏
从这个定义可以看出合成模式大致有三个特点,一具用两种对象,简单对象和复杂对象,但两种对象对客户程序具有相同接口,二具有层次结构。三具有递归特性。
从这些条件看来,我们的系统确实简单的多,对于客户程序来说,完全不知道有复杂对象,由于工厂的介入,系统不会有递归的情况出现,并且,对于该系统也没有递 归的要求。其实,这个输出系统是组合模式,工厂模式,及宽窄接口方式综合的来解决问题的。若上来就硬套一种模式的话,一定会带来很大的麻烦。