2020-05-28 01:45:29
在JavaScript中实现组合模式需通过定义抽象组件接口,并分别实现叶子节点与组合节点,利用树形结构统一处理“整体-部分”关系。具体实现步骤如下:
1. 定义抽象组件接口抽象组件作为基类,声明所有节点共有的操作方法(如add、remove、operation),并默认抛出错误以强制子类实现。
class Component { constructor(name) { this.name = name; } add(component) { throw new Error("Cannot add to a leaf node."); } remove(component) { throw new Error("Cannot remove from a leaf node."); } getChild(index) { throw new Error("Cannot get child from a leaf node."); } operation() { throw new Error("Operation must be implemented by subclasses."); }}2. 实现叶子节点(Leaf)叶子节点代表不可再分的最小单元,仅实现自身操作逻辑,不支持增删子节点。
class Leaf extends Component { constructor(name) { super(name); } operation() { return `Leaf: ${this.name}`; }}3. 实现组合节点(Composite)组合节点维护子组件列表,支持动态增删子节点,并通过递归调用子节点的operation方法实现统一行为。
class Composite extends Component { constructor(name) { super(name); this.children = []; } add(component) { this.children.push(component); } remove(component) { const index = this.children.indexOf(component); if (index > -1) { this.children.splice(index, 1); } } getChild(index) { return this.children[index]; } operation() { let result = `Composite: ${this.name}n`; for (const child of this.children) { result += " " + child.operation() + "n"; } return result; }}4. 使用示例构建树形结构并调用根节点的operation方法,递归输出所有节点信息。
const root = new Composite("Root");const branch1 = new Composite("Branch1");const branch2 = new Composite("Branch2");const leaf1 = new Leaf("Leaf1");const leaf2 = new Leaf("Leaf2");const leaf3 = new Leaf("Leaf3");branch1.add(leaf1);branch1.add(leaf2);branch2.add(leaf3);root.add(branch1);root.add(branch2);console.log(root.operation());// 输出:// Composite: Root// Composite: Branch1// Leaf: Leaf1// Leaf: Leaf2// Composite: Branch2// Leaf: Leaf3组合模式的核心优势与适用场景统一处理:客户端无需区分单个对象与组合对象,简化代码逻辑。
动态扩展:支持运行时增删组件,灵活构建复杂结构。
需表示层次结构(如文件系统、UI组件、组织架构)。
需忽略对象差异,统一处理“整体-部分”关系。
需动态调整组件结构(如增删节点)。
目的:表示对象的组成关系(“是什么”)。
实现:通过树形结构递归处理子节点。
目的:动态扩展对象行为(“做什么”)。
实现:通过包装原始对象,逐层添加新功能。
组合模式通过树形结构与统一接口设计,实现了对复杂层次结构的高效管理。其核心在于抽象组件接口、叶子节点与组合节点的分工,以及递归行为的统一处理。在需要动态构建层次化对象的场景中(如文件系统、UI组件树),组合模式能显著简化客户端代码,但需避免过度设计导致类数量膨胀。