Technology-设计模式-组合模式

本文介绍了GoF中的组合模式。

模式推演

对树形结构进行操作时:

当我们需要对一个树形的对象集合进行操作,例如遍历时:

Technology-DesignPattern-Composite-Request

由于每一个节点都可能有子节点的枝节点,也可能是没有子节点的叶节点,我们希望能在处理这两类时,能用统一的处理方式,把枝节点和叶节点的方法统一封装成接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Component {
// Leaf
public void operation();
// Branch
public void add(Component comp);
public void remove(Component comp);
public Component getChild(int index);
}
public class Leaf extends Component {
public void operation();
}
public class Composite extends Component {
public void operation();
public void add(Component comp);
public void remove(Component comp);
public Component getChild(int index);
}

这里的枝节点和叶节点继承自同一个基类,所以我们在处理时,可以针对抽象进行交互,而无需理会其类型。但是由于枝节点里面包含了多个叶节点,所以,这里我们需要用到迭代器。

一般的迭代器写法如下:

1
2
3
4
5
6
7
8
9
10
11
public class Composite extends Component {
ArrayList<Component> childs;
public void operation(){
Iterator iterator = childs.iterator();
while(iterator.hasNext()){
Component comp = iterator.next();
comp.operation();
}
}
}

这样写,如果枝节点包含的都是叶节点,是可以的,但是如果枝节点包含了枝节点,我们没办法单独处理该子枝节点中的叶节点,所以需要改进:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class ComponentIterator implements Iterator<Component> {
Stack<Iterator<Component>> stack = new Stack<Iterator<Component>>();
public ComponentIterator(Iterator<Component> iterator){
stack.push(iterator);
}
@Override
public boolean hasNext() {
if(stack.isEmpty())
return false;
Iterator<Component> iterator = stack.peek();
if(!iterator.hasNext()){
stack.pop();
return hasNext();
}else{
return true;
}
}
@Override
public Component next() {
if(hasNext()){
Iterator<Component> iterator = stack.peek();
Component comp = iterator.next();
if(comp instanceof Composite)
stack.push(comp.iterator());
return comp;
}else{
return null;
}
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}

定义

组合模式(Composite Pattern):允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。

类图:

Technology-DesignPattern-Composite-Class

YI wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!