组合模式在树形结构中的应用与电商实现
组合模式核心原理
组合模式属于结构型设计模式,核心目标是将对象组织为树形层次结构,使客户端能统一处理单个对象和对象集合。通过抽象接口实现元素与元素集合的操作一致性,例如处理文件时无需区分单个文件或文件夹。
生活实例解析
文件系统是典型应用场景:
- 叶子元素:单个文件(如 report.docx)
- 复合元素:文件夹(含子文件和子文件夹)
- 统一操作:所有元素支持 getSize() 和 display() 等通用方法
模式核心组件
| 角色 | 职责 |
|---|---|
| 抽象组件 | 定义统一接口(如 Element) |
| 叶子节点 | 基础单元(无子元素) |
| 复合节点 | 容器对象(可包含子元素) |
文件系统实现示例
1. 抽象组件定义
public abstract class FileElement {
protected String id;
public abstract long calculateSize();
public abstract void display(int depth);
public void addElement(FileElement e) {
throw new UnsupportedOperationException();
}
}
2. 叶子节点实现
public class Document extends FileElement {
private long bytes;
public Document(String id, long bytes) {
this.id = id;
this.bytes = bytes;
}
@Override
public long calculateSize() {
return bytes;
}
@Override
public void display(int depth) {
System.out.println(" ".repeat(depth) + "文档: " + id);
}
}
3. 复合节点实现
public class FileContainer extends FileElement {
private List<FileElement> items = new ArrayList<>();
@Override
public long calculateSize() {
return items.stream().mapToLong(FileElement::calculateSize).sum();
}
@Override
public void display(int depth) {
System.out.println(" ".repeat(depth) + "目录: " + id);
items.forEach(item -> item.display(depth + 1));
}
@Override
public void addElement(FileElement e) {
items.add(e);
}
}
电商分类系统实战
领域模型设计
| 模式角色 | 电商实现 |
|---|---|
| 抽象组件 | CatalogComponent |
| 叶子节点 | ProductItem |
| 复合节点 | ProductCategory |
核心实现代码
// 抽象组件
public abstract class CatalogComponent {
public abstract int countItems();
public abstract void showStructure(int level);
}
// 商品叶子节点
public class ProductItem extends CatalogComponent {
private String sku;
private int stock;
@Override
public int countItems() {
return 1;
}
@Override
public void showStructure(int level) {
System.out.println(" ".repeat(level) + "商品: " + sku);
}
}
// 分类复合节点
public class ProductCategory extends CatalogComponent {
private List<CatalogComponent> children = new ArrayList<>();
@Override
public int countItems() {
return children.stream().mapToInt(CatalogComponent::countItems).sum();
}
@Override
public void showStructure(int level) {
System.out.println(" ".repeat(level) + "分类: " + id);
children.forEach(child -> child.showStructure(level + 1));
}
public void addChild(CatalogComponent child) {
children.add(child);
}
}
客户端调用示例
// 构建分类树
ProductCategory electronics = new ProductCategory("C1", "电子产品");
ProductCategory phones = new ProductCategory("C2", "手机");
ProductItem phone1 = new ProductItem("P1001", "智能手机", 100);
phones.addChild(phone1);
electronics.addChild(phones);
// 统一操作
electronics.showStructure(0);
System.out.println("商品总数: " + electronics.countItems());
应用场景分析
- 文件系统:文档与目录管理
- 组织架构:部门与子部门层级
- UI组件:容器组件与基础组件
- 电商系统:商品分类与商品项管理
实现要点
- 采用透明式设计:抽象组件声明所有方法
- 复合节点递归处理子元素
- 新增元素类型不影响客户端逻辑
- 叶子节点与复合节点保持接口一致性