简介
《大话设计模式》一书中对组合模式的定义为:
将对象组合成【树】形结构以表示【部分-整体】的层次结构,组合模式使得用户对【单个对象】和对【组合对象】的使用具有一致性。
组合模式有时候又叫做部分-整体模式,它使我们在树型结构的问题中,
模糊了简单元素和复杂元素的概念
。
当发现需求中是体现
部分与整体层次结构,并且你希望用户可以
忽略组合对象与单个对象的不同,以统一的方式使用组合结构中的所有对象时,就应该考虑组合模式了。
组合模式解耦了客户程序与复杂元素内部结构,从而使客户程序可以像处理简单元素一样来处理复杂元素。
组合模式让你可以优化处理
【递归】或【分级】数据结构。
关于分级数据结构的一个普遍性的例子是你每次使用电脑时所遇到的
文件系统。文件系统由
目录和文件组成,每个目录都可以装内容,目录的内容可以是文件,也可以是目录。按照这种方式,计算机的文件系统就是以
递归结构来组织的。如果你想要描述这样的数据结构,那么你可以使用组合模式。
涉及角色:
- Component:为参加组合的对象声明一个公共接口,不管是组合还是叶结点
- Leaf:在组合中表示叶子结点对象,叶子结点没有子结点
- Composite:表示参加组合的有子结点的对象
特点:使得客户端看来单个对象和对象的组合是同等的。换句话说,某个类型的方法同时也接受自身类型作为参数。
例如:java.util.List#addAll(Collection)
组合模式
Component:为参加组合的对象声明一个公共接口,不管是组合还是叶结点。
public abstract class Component {
/**表示直接叶子节点(直接下属团队成员)的集合 */
protected List<Component> employList;
public String name;
public final void display() {
System.out.println(name);//打印自己
display(employList);//打印子节点
}
private final void display(List<Component> list) {
if (list != null) {
for (int i = 0; i < list.size(); i++) {
Component sonComponent = list.get(i);//子节点
System.out.println(sonComponent.name);//打印子节点
List<Component> sonList = sonComponent.employList;//子节点的节点集合
if (sonList != null) {//不为空说明是非叶子节点
display(sonList);
}
}
}
}
public abstract boolean add(Component employer);
public abstract boolean delete(Component employer);
}
1
public abstract class Component {
2
/**表示直接叶子节点(直接下属团队成员)的集合 */
3
protected List<Component> employList;
4
public String name;
5
6
public final void display() {
7
System.out.println(name);//打印自己
8
display(employList);//打印子节点
9
}
10
11
private final void display(List<Component> list) {
12
if (list != null) {
13
for (int i = 0; i < list.size(); i++) {
14
Component sonComponent = list.get(i);//子节点
15
System.out.println(sonComponent.name);//打印子节点
16
List<Component> sonList = sonComponent.employList;//子节点的节点集合
17
if (sonList != null) {//不为空说明是非叶子节点
18
display(sonList);
19
}
20
}
21
}
22
}
23
24
public abstract boolean add(Component employer);
25
public abstract boolean delete(Component employer);
26
}
Leaf:组合中的叶子结点对象,叶子结点没有子结点
public class Leaf extends Component {
public Leaf(String name) {
this.name = name;
this.employList = null;//没有叶子节点
}
@Override
public boolean add(Component employer) {
throw new RuntimeException("叶子结点没有子结点");
}
@Override
public boolean delete(Component employer) {
throw new RuntimeException("叶子结点没有子结点");
}
}
x
1
public class Leaf extends Component {
2
public Leaf(String name) {
3
this.name = name;
4
this.employList = null;//没有叶子节点
5
}
6
7
8
public boolean add(Component employer) {
9
throw new RuntimeException("叶子结点没有子结点");
10
}
11
12
public boolean delete(Component employer) {
13
throw new RuntimeException("叶子结点没有子结点");
14
}
15
}
Composite:组合中有子结点对象
public class Composite extends Component {
public Composite(String name) {
this.name = name;
this.employList = new ArrayList<Component>();
}
@Override
public boolean add(Component employer) {
return this.employList.add(employer);
}
@Override
public boolean delete(Component employer) {
return this.employList.remove(employer);
}
}
1
public class Composite extends Component {
2
public Composite(String name) {
3
this.name = name;
4
this.employList = new ArrayList<Component>();
5
}
6
7
8
public boolean add(Component employer) {
9
return this.employList.add(employer);
10
}
11
12
public boolean delete(Component employer) {
13
return this.employList.remove(employer);
14
}
15
}
演示
public class Test {
public static void main(String[] args) {
Component employer1 = new Composite("【项目经理一】");
Component employer11 = new Leaf("包青天");
Component employer12 = new Leaf("白乾涛");
Component employer13 = new Leaf("baiqiantao");
Component employer2 = new Composite("【项目经理二】");
Component employer21 = new Leaf("bqt");
Component employer3 = new Composite("boss");
employer3.add(employer1);// 为boss添加一个非叶子节点
employer3.add(employer2);
employer1.add(employer11);// 为项目经理添加一个叶子节点
employer1.add(employer12);
employer1.add(employer13);
employer2.add(employer21);
employer11.display();
System.out.println("----------------------------------");
employer1.display();
System.out.println("----------------------------------");
employer2.display();
System.out.println("----------------------------------");
employer3.display();
System.out.println("----------------------------------");
System.out.println(employer2.add(employer21));//true
System.out.println(employer2.delete(employer11));//false
employer2.display();
}
}
x
1
public class Test {
2
public static void main(String[] args) {
3
Component employer1 = new Composite("【项目经理一】");
4
Component employer11 = new Leaf("包青天");
5
Component employer12 = new Leaf("白乾涛");
6
Component employer13 = new Leaf("baiqiantao");
7
8
Component employer2 = new Composite("【项目经理二】");
9
Component employer21 = new Leaf("bqt");
10
11
Component employer3 = new Composite("boss");
12
employer3.add(employer1);// 为boss添加一个非叶子节点
13
employer3.add(employer2);
14
15
employer1.add(employer11);// 为项目经理添加一个叶子节点
16
employer1.add(employer12);
17
employer1.add(employer13);
18
19
employer2.add(employer21);
20
21
employer11.display();
22
System.out.println("----------------------------------");
23
employer1.display();
24
System.out.println("----------------------------------");
25
employer2.display();
26
System.out.println("----------------------------------");
27
employer3.display();
28
System.out.println("----------------------------------");
29
30
System.out.println(employer2.add(employer21));//true
31
System.out.println(employer2.delete(employer11));//false
32
employer2.display();
33
}
34
}
2018-2-22