定义:
Compose objects into tree structures to represent part-whole hierarchies.Composite lets clients treat individual objects and compositions of objects uniformly.
将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
从定义中可知,组合模式的组合,是将一些对象组合成树形结构,这样我们就可以不用关心处理的是单个对象还是组合对象,因为我们对它的访问具有一致性。
UML图
从图中可知,组合模式包括3个部分:
1.抽象构件角色Component
———— 定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性。
2.叶子构件Leaf
———— 叶子对象,相当于子节点。
3.树枝构件Composite
———— 树枝对象,它的作用是组合树枝节点和叶子节点形成一个树形结构,并管理子部件,通常包含Add()、Remove()、getChild()等方法。
组合模式分为透明式的组合模式、安全式的组合模式,下面我们通过代码来看一下透明式的组合模式。
1.创建抽象构件角色Component
public abstract class Component {
protected String name;
public Component(String name) {
this.name = name;
}
public void print() {
print(0);
}
abstract void print(int level);
abstract public void add(Component component);
abstract public void remove(Component component);
}
2.创建树枝构件Composite
public class Composite extends Component {
private List<Component> child;
public Composite(String name) {
super(name);
child = new ArrayList<>();
}
@Override
void print(int level) {
for (int i = 0; i < level; i++) {
System.out.print("--");
}
System.out.println("Composite:" + name);
for (Component component : child) {
component.print(level + 1);
}
}
//添加对象
@Override
public void add(Component component) {
child.add(component);
}
//移除对象
@Override
public void remove(Component component) {
child.remove(component);
}
}
3.创建叶子构件Leaf
public class Leaf extends Component {
public Leaf(String name) {
super(name);
}
@Override
void print(int level) {
for (int i = 0; i < level; i++) {
System.out.print("--");
}
System.out.println("left:" + name);
}
//在透明式的组合模式中叶子构件没有add和remove等方法,但非要实现,所有只能空实现或抛异常。
@Override
public void add(Component component) {
throw new UnsupportedOperationException();
}
@Override
public void remove(Component component) {
throw new UnsupportedOperationException();
}
}
4.测试
public class Test{
public static void main(String[] args) {
Composite root = new Composite("root");
Component node1 = new Leaf("1");
Component node2 = new Composite("2");
Component node3 = new Leaf("3");
root.add(node1);
root.add(node2);
root.add(node3);
Component node21 = new Leaf("21");
Component node22 = new Composite("22");
node2.add(node21);
node2.add(node22);
Component node221 = new Leaf("221");
node22.add(node221);
root.print();
}
}
result:
Composite:root
--left:1
--Composite:2
----left:21
----Composite:22
------left:221
--left:3
上述代码中,通过list集合储存component,使用add()、remove()等方法管理component,将对象与对象之间组合起来,形成一个树形结构。单个对象是一个部分,对象与对象之间又成为一个整体,像目录、菜单、文件夹管理等等都可以通过组合模式来实现。
总结
1.使用场景:
- 维护和展示部分-整体关系的场景,如树形菜单、文件和文件夹管理。
- 从一个整体中能够独立出部分模块或功能的场景。
2.优点:
1、高层模块调用简单,无需考虑是单个对象还是组合对象 2、节点自由增加,满足开闭原则
3.缺点:
1、设计较为复杂、层次关系不易理清 2、不容易限制容器中的构件