结构型:组合模式
目录
1、核心思想
2、实现方式
2.1 模式结构
2.2 实现案例
3、优缺点分析
4、适用场景
1、核心思想
目的:将总是在重复、迭代地显示的某种自相似性的结构(部分与整体结构特征相似),例如树形结构,以统一的方式处理单个对象和对象组合,最终达到对象复杂的层次结构与客户端解耦的目的。
解决思路:用组合模式来表达“部分/整体”的层次结构,提取并抽象其相同的部分,特殊化其不同的部分,以提高系统的可复用性与可扩展性,最终达到以不变应万变的目的。
举例:
1> 蕨类植物的叶子,不管从哪个层级观察这片叶子,我们都会得到一个固定的结构,这意味着组成植物叶子的部分或整体都有着相同的生长方式。
2> 二叉树,此结构始于其开端的“根”节点,往下分出来两个“枝”节点(左右2个节点),接着每个枝节点又可以继续“分枝”,直至其末端的“叶”节点为止。
2、实现方式
2.1 模式结构
三个核心结构:
- Component(组件接口):所有复合节点与叶节点的高层抽象,定义出需要对组件操作的接口标准(声明管理子组件的方法(如透明模式)或仅定义公共行为(如安全模式))。
- Composite(复合组件):包含多个子组件对象(List<Node>,可以是复合组件或叶端组件)的复合型组件,负责管理子组件(添加、删除、遍历),并委托操作到所有子节点。
- Leaf(叶端组件):不包含子组件的终端组件,同样实现组件接口中定义的操作方法。通常不实现子组件管理方法(如
add
),若数据接口标准,可抛出异常。
2.2 实现案例
文件系统:文件系统由文件和文件夹构成,文件夹可包含文件或其他文件夹(tree);可以层级打印文件结构(tree)。
// 组件接口
public abstract class Node {protect String name;//节点命名public Node(String name) {//构造方法需传入节点名this.name = name;}//增加后续子节点方法public abstract void add(Node child);public void tree(int space) {for(int i=0; i < space; i++) {System.out.print(" ");//先循环输入space个空格}System.out.println(name);//接着再输出自己的名字}//无参重载方法,默认从第0列开始展示public void tree() {this.tree(0);}
}// 组合:文件夹
class Folder implements Node{// 文件夹可以包含子节点(子文件夹或文件)private List<Node> children = new ArrayList<>();public Folder(String name) { super(name);// 调用父类“节点”的构造方法命名}public void add(Node child) {children.add(child);//可以添加子节点}@Overridepublic void tree() {super.tree(space); //调用父类通用的tree方法列出自己的名字space++; //在循环的子节点前,空格数要加1for (Node child: children) {child.tree(); // 调用子节点的tree方法}}
}// 叶子:文件
class File implements Node{public File(String name) { super(name);}public void add(Node child) {System.out.println("不能添加子节点");}@Overridepublic void tree() {super.tree(space);}
}// 客户端调用
public class Client {public static void main(String[] args) {Folder root = new Folder("D盘");root.add(new File("简历.pdf"));Folder subFolder = new Folder("图片");subFolder.add(new File("1.jpg"));subFolder.add(new File("2.png"));root.add(subFolder);root.tree();}
}
3、优缺点分析
优点:
-
统一处理:客户端无需区分叶子节点和组合节点。
-
扩展性强:新增组件类型无需修改现有代码,符合开闭原则。
-
树形结构支持:天然适合递归和层次化数据管理。
缺点:
-
接口设计挑战:
-
透明模式:叶子需实现不相关方法(如
add
),可能抛出异常。 -
安全模式:客户端需类型检查,失去透明性。
-
-
性能开销:递归遍历可能影响性能(深层次结构)。
4、适用场景
-
树形结构表示:文件系统、菜单/子菜单、组织架构。
-
递归操作需求:统计目录大小、渲染UI组件树。
-
统一处理逻辑:对单个对象和组合对象执行相同操作(如复制、删除)。