结构型-组合模式
2026/1/15大约 3 分钟Java设计模式结构型模式组合模式Java设计模式面向对象架构设计最佳实践代码优化
概述
组合模式(Composite Pattern)将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
适用场景
- 想表示对象的部分-整体层次结构
- 希望用户忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象
角色组成
- Component(抽象构件):声明接口,实现所有类共有接口的默认行为
- Leaf(叶子构件):表示叶子节点对象
- Composite(容器构件):存储子部件,实现与子部件有关的操作
代码实现
1. 抽象构件
public abstract class Component {
protected String name;
public Component(String name) {
this.name = name;
}
public abstract void add(Component component);
public abstract void remove(Component component);
public abstract void display(int depth);
}2. 叶子构件
public class Leaf extends Component {
public Leaf(String name) {
super(name);
}
@Override
public void add(Component component) {
throw new UnsupportedOperationException("叶子节点不能添加子节点");
}
@Override
public void remove(Component component) {
throw new UnsupportedOperationException("叶子节点不能删除子节点");
}
@Override
public void display(int depth) {
System.out.println("-".repeat(depth) + name);
}
}3. 容器构件
public class Composite extends Component {
private List<Component> children = new ArrayList<>();
public Composite(String name) {
super(name);
}
@Override
public void add(Component component) {
children.add(component);
}
@Override
public void remove(Component component) {
children.remove(component);
}
@Override
public void display(int depth) {
System.out.println("-".repeat(depth) + name);
for (Component child : children) {
child.display(depth + 2);
}
}
}4. 客户端
public class Client {
public static void main(String[] args) {
Composite root = new Composite("根目录");
Composite folder1 = new Composite("文件夹1");
folder1.add(new Leaf("文件1.txt"));
folder1.add(new Leaf("文件2.txt"));
Composite folder2 = new Composite("文件夹2");
folder2.add(new Leaf("文件3.txt"));
root.add(folder1);
root.add(folder2);
root.add(new Leaf("readme.md"));
root.display(0);
}
}# 输出
根目录
--文件夹1
----文件1.txt
----文件2.txt
--文件夹2
----文件3.txt
--readme.md类图
实际案例:公司组织架构
// 组织抽象类
public abstract class Organization {
protected String name;
public Organization(String name) {
this.name = name;
}
public abstract void add(Organization org);
public abstract void remove(Organization org);
public abstract void print(String prefix);
}
// 部门(容器)
public class Department extends Organization {
private List<Organization> children = new ArrayList<>();
public Department(String name) {
super(name);
}
@Override
public void add(Organization org) {
children.add(org);
}
@Override
public void remove(Organization org) {
children.remove(org);
}
@Override
public void print(String prefix) {
System.out.println(prefix + "📁 " + name);
for (Organization child : children) {
child.print(prefix + " ");
}
}
}
// 员工(叶子)
public class Employee extends Organization {
private String position;
public Employee(String name, String position) {
super(name);
this.position = position;
}
@Override
public void add(Organization org) {
throw new UnsupportedOperationException();
}
@Override
public void remove(Organization org) {
throw new UnsupportedOperationException();
}
@Override
public void print(String prefix) {
System.out.println(prefix + "👤 " + name + " (" + position + ")");
}
}
// 使用
public class Client {
public static void main(String[] args) {
Department company = new Department("科技公司");
Department dev = new Department("研发部");
dev.add(new Employee("张三", "Java开发"));
dev.add(new Employee("李四", "前端开发"));
Department hr = new Department("人事部");
hr.add(new Employee("王五", "HR"));
company.add(dev);
company.add(hr);
company.add(new Employee("赵六", "CEO"));
company.print("");
}
}# 输出
📁 科技公司
📁 研发部
👤 张三 (Java开发)
👤 李四 (前端开发)
📁 人事部
👤 王五 (HR)
👤 赵六 (CEO)透明模式 vs 安全模式
透明模式
// 所有方法都在抽象类中声明
public abstract class Component {
public abstract void add(Component c);
public abstract void remove(Component c);
public abstract Component getChild(int i);
public abstract void operation();
}安全模式
// 只在 Composite 中声明管理方法
public abstract class Component {
public abstract void operation();
}
public class Composite extends Component {
public void add(Component c) { }
public void remove(Component c) { }
public Component getChild(int i) { return null; }
public void operation() { }
}JDK 中的应用
java.awt.Container和java.awt.Componentjavax.swing.JComponentjava.io.File(文件和目录)
优缺点
优点:
- 定义了包含基本对象和组合对象的类层次结构
- 简化客户端代码
- 更容易增加新类型的组件
缺点:
- 设计较复杂
- 不容易限制容器中的构件类型
