目录
1.组合模式定义
2.优点
3.缺点
4.结构说明
5.工作流程
6.示例
7.应用场景
8.本质
9.涉及的设计原则
10.相关的设计模式
11.开源框架中的应用
组合模式定义
将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
优点
- 可以构建复杂的树形结构,表示复杂的部分-整体关系。
- 客户端代码具有一致性,不需要区分 Leaf 和 Composite,统一处理。
- 易于扩展,可以轻松添加新类型的组件。
缺点
- 可能会限制组件的类型,因为通用接口可能无法涵盖所有具体组件的操作。
- 可能导致设计过度复杂
结构说明
- Component(组件):定义了组合中的对象的通用接口,可以包括叶子节点和容器节点的共有操作。
- Leaf(叶子节点):表示组合中的叶子节点对象,它没有子节点。
- Composite(容器节点):表示组合中的容器节点对象,它可以包含子节点,通常会实现通用操作,同时管理子节点。
工作流程
- 客户端通过 Component 接口与组合结构进行交互。
- 组合结构中的 Leaf 和 Composite 都实现了 Component 接口,因此可以递归地构建树形结构。
- 客户端可以以一致的方式对待 Leaf 和 Composite,因为它们都遵循 Component 接口。
示例
1.创建Component组件,定义对象中的通用方法。
结构型-组合模式:Component对象声明接口,适当情况下实现所有类共有接口的默认行为
*/
public abstract class Component {
protected String name;
public Component(String name){
this.name = name;
}
public abstract void add(Component c);
public abstract void remove(Component c);
public abstract void display(int depth);
}
2. 创建Leaf叶子节点,注意叶子节点是没有子节点的。
/*
叶子节点不具备添加和移除子节点的能力
*/
public class Leaf extends Component{
public Leaf(String name) {
super(name);
}
@Override
public void add(Component c) {
System.out.println("Cannot add component...");
}
@Override
public void remove(Component c) {
System.out.println("Cannot remove component...");
}
@Override
public void display(int depth) {
System.out.println("-" + depth);
}
}
3.创建Composite容器,包含子节点,管理子节点。
/*
树结构中的子节点实现:包含list
*/
public class Composite extends Component{
private List<Component> children = new ArrayList<>();
public Composite(String name) {
super(name);
}
@Override
public void add(Component c) {
children.add(c);
}
@Override
public void remove(Component c) {
children.remove(c);
}
@Override
public void display(int depth) {
System.out.println("-" + depth + name);
for (Component component:children) {
component.display(depth + 2);
}
}
}
客户端代码:
public class ComponentClient {
public static void main(String[] args) {
Composite root = new Composite("root");
root.add(new Leaf("A"));
root.add(new Leaf("B"));
Composite comp = new Composite("component X");
comp.add(new Leaf("XA"));
comp.add(new Leaf("XB"));
root.add(comp);
root.display(1);
}
}
应用场景
- 当需要表示对象的部分-整体层次结构时,例如树形结构、菜单、文件系统等。
- 当客户端需要以一致的方式处理单个对象和对象组合时。
本质
将对象组合成树形结构以表示部分-整体的关系,允许客户端统一处理对象和对象组合。使用组 合模式的前提在于,你的业务场景必须能够表示成树形结构。所以,组合模式的应用场景也 比较局限,它并不是一种很常用的设计模式。
涉及的设计原则
- 单一职责原则:每个类应该有一个单一的责任,Leaf 类负责叶子节点,Composite 类负责容器节点。
- 开闭原则:组合模式使得添加新类型的组件变得容易,因为客户端代码不需要修改。
- 里氏替换原则:客户端代码可以使用 Component 接口,不需要关心具体的 Leaf 或 Composite 类型。
相关的设计模式
- 组合模式通常与迭代器模式结合使用,以便客户端可以遍历组合结构中的元素。
- 组合模式也与装饰者模式结合使用,以为组合结构中的对象添加额外的功能。
开源框架中的应用
一个文件系统的树形结构可以使用组合模式来表示,其中目录是容器节点(Composite),文件是叶子节点(Leaf)。客户端可以统一处理目录和文件,执行操作如打印目录结构、计算总文件大小等。一些开源框架中也使用了组合模式,例如 Java AWT 和 Swing GUI 组件库中的图形界面组件树。