技术开发 频道

从Java类库看设计模式

  毫无疑问的,AWT中的Component-Container体系就是一个很好的Composite模式的例子。Container继承于Component,而Container中有可以包含有多个Component,因为Container实际上也是Component,因而Container也可以包含Container。这样通过Component-Container结构的对象组合,形成一个树状的层次结构。这也就是Composite模式所要做的。

  Composite模式是为了简化编程而提出的,一般的在编程的时候,如果严格的区分Component和Container的话,有时候会带来许多不便,而且这些往往是没有必要的。比如,我要在一个Container中放置一个Component,我并不需要知道这个Component到底是一个Container,或者就是一个一般的Component,在父级容器中所要做的,只是记录一个Component的引用,在需要的时候调用Component的绘制方法来显示这个Component。当这个Component确实是一个Container的时候,它可以通过Container重载后的绘制方法,完成对这个容器的显示,并把绘制消息传递给到它的子对象去。也就是说,对一个父级容器而言,它并不不关心,其子对象到底是一个Component,还是一个Container。它需要将Component和Container统一对待。

  图十一:Composite模式的类图

  Composite模式比较简单,实现起来也不复杂,但是有一定的局限性。比如,在处理树的时候,我们往往需要处理三类对象:子树,页节点和非页节点。而在Composite模式中对于子树和非叶节点的区分并不明显,而是把他们合成为一个Composite对象了。而且在GOF给出的Composite的模式中,对于添加,删除子节点等属于Composite对象的的方法,是放在了Component对象中的,这虽然在实现的时候可以区分开来,但容易造成一些概念上的误解。

  由上所叙,我们可以提出一个改进了的Composite模式,引入子树对象,从而将子树和非叶节点分开,如下图所示:

  图十二:Composite模式的一种变体

  虽然将Composite从Component类层次中分离出来,但并没有损害Composite模式的内涵。这样做不一定就会比上面的那个要好,各有不同的应用,不过有时候用这样的方法来处理子树要容易些,概念上也更为清晰。

  下面的代码,给出了一个Composite模式简单的Java实现:

1  public abstract class Component{
2
3   public abstract void operation();
4
5   public void add(Component component){};
6
7   public void remove(Component component){};
8
9   }
10
11   import java.util.*;
12
13   public class Composite extends Component{
14
15   String name;
16
17   ArrayList children = new ArrayList();
18
19   public Composite(String name){
20
21   this.name = name;
22
23   }
24
25   public void add(Component component){
26
27   children.add(component);
28
29   }
30
31   public void remove(Component component){
32
33   children.remove(component);
34
35   }
36
37   public void operation(){
38
39   System.out.println(name);
40
41   Iterator iterator = children.iterator();
42
43   while(iterator.hasNext()){
44
45   Component child = (Component)iterator.next();
46
47   child.operation();
48
49   }
50
51   }
52
53   }
54
55   public class Leaf extends Component{
56
57   String name;
58
59   public Leaf(String name){
60
61   this.name = name;
62
63   }
64
65   public void operation(){
66
67   System.out.println(name);
68
69   }
70
71   }
72
0
相关文章