设计模式: 结构型之组合模式(6)

组合模式概述

  • 组合模式(Composite Pattern)是一种结构型设计模式,它允许你将对象组合成树形结构以表示"部分-整体"的层次结构
  • 组合模式使得客户端对单个对象和复合对象的使用具有一致性
  • 在 TypeScript 中,组合模式通常涉及到一个接口(或抽象类),它定义了用于操作组件的方法
  • 然后,有两个具体的类实现这个接口
    • 一个是叶子节点类,它表示树形结构中的基本对象
    • 另一个是组合类,它表示包含其他组件的复合对象

组合模式示例

ts 复制代码
// 定义组件接口  
interface Component {  
  operation(): void;  
  add(component: Component): void;  
  remove(component: Component): void;  
  getChild(index: number): Component;  
}  
  
// 叶子节点类  
class Leaf implements Component {  
  private name: string;  
  
  constructor(name: string) {  
    this.name = name;  
  }  
  
  operation(): void {  
    console.log(`Leaf operation: ${this.name}`);  
  }  
  
  add(component: Component): void {  
    throw new Error("Leaf cannot add components");  
  }  
  
  remove(component: Component): void {  
    throw new Error("Leaf cannot remove components");  
  }  
  
  getChild(index: number): Component {  
    throw new Error("Leaf has no children");  
  }  
}  
  
// 组合类  
class Composite implements Component {  
  private children: Component[] = [];  
  
  operation(): void {  
    console.log("Composite operation");  
    for (const child of this.children) {  
      child.operation();  
    }  
  }  
  
  add(component: Component): void {  
    this.children.push(component);  
  }  
  
  remove(component: Component): void {  
    const index = this.children.indexOf(component);  
    if (index !== -1) {  
      this.children.splice(index, 1);  
    }  
  }  
  
  getChild(index: number): Component {  
    if (index < 0 || index >= this.children.length) {  
      throw new Error("Index out of range");  
    }  
    return this.children[index];  
  }  
}  
  
// 使用示例  
const composite = new Composite();  
const leaf1 = new Leaf("Leaf 1");  
const leaf2 = new Leaf("Leaf 2");  
composite.add(leaf1);  
composite.add(leaf2);  
composite.operation(); // 输出: Composite operation, Leaf operation: Leaf 1, Leaf operation: Leaf 2
  • 这里定义了一个接口:Component
  • 使用 Leaf 和 Composite 继承 Component
    • Leaf 类实现了 Component 接口,表示叶子节点,它只包含 operation 方法的实现,其他方法都抛出了错误,因为叶子节点不应该有子节点
    • Composite 类也实现了 Component 接口,表示复合节点,它包含了所有方法的实现,包括操作自身和子节点的方法
  • 最后,我们创建了一个 Composite 实例作为根节点,并向其中添加了两个 Leaf 实例作为子节点,然后调用了 operation 方法来演示组合模式的使用

组合模式的应用

  • 组合模式(Composite Pattern)的应用场景主要体现在那些需要表示对象的部分-整体层次结构
  • 并且希望客户端能以相同方式处理单个对象和对象集合的情况
  • 以下是组合模式的一些典型应用领域

1 ) 文件系统

  • 在文件系统中,目录(folders)和文件(files)可以构成一个层级结构
  • 目录可以包含子目录和文件,而文件则是叶子节点
  • 组合模式允许我们以统一的方式来操作文件和目录,例如创建、删除、移动、列出内容等,无论处理的是单个文件还是整个目录结构

2 ) GUI 组件库

  • 在图形用户界面(GUI)开发中,窗口、面板、按钮等控件可以嵌套组成复杂的界面结构
  • 组合模式使得我们可以一致地处理顶级容器组件(如窗口)和子组件(如按钮)
  • 无论是添加、删除、布局或绘制组件,都可以采用同样的接口进行

3 ) 组织结构

  • 在企业管理系统中,组织架构通常是一个分层结构,包括部门、小组和个人员工
  • 使用组合模式可以方便地管理和展示这种层级关系,如查询某个员工的所有上级领导、计算某个部门的总人数、调整组织架构等

4 ) HTML DOM 树

  • 浏览器中的 HTML 文档对象模型(DOM)就是一个典型的组合模式实例。

  • DOM 节点可以是元素节点(如

    ),也可以是文本节点,它们共同构成了一个树形结构。

  • 开发者可以以统一的方式遍历、修改或操作 DOM 树中的任何节点,不论它是叶节点(文本节点)还是复合节点(元素节点及其子节点)

5 ) 游戏开发

  • 在游戏引擎中,场景可能包含多个实体,这些实体可能是独立的游戏对象,也可能是包含多个子对象的复杂对象,如角色由身体、头部、四肢等部件组成
  • 组合模式允许开发者以一致的方式来处理单个对象的动作、渲染和其他功能,无论对象是否包含子对象

6 ) XML/JSON 数据解析

  • 解析 XML 或 JSON 数据时,文档结构通常包含嵌套的元素或对象
  • 组合模式可以用来构建解析器,使其能以同样的方式处理简单的元素和含有子元素的复杂元素

7 ) 总结来说

  • 组合模式的应用在于它帮助我们构造和管理树形结构的数据和对象,简化了处理复杂层次结构的逻辑
  • 并且降低了客户端代码与结构内部细节之间的耦合度

组合模式不适用场景

  • 组合模式虽然是一种强大的设计模式,但并非所有场景都适合使用它
  • 以下是一些组合模式不适合应用的地方

1 ) 简单的对象结构

  • 如果应用程序中的对象结构相对简单,且不需要复杂的组合和嵌套,那么使用组合模式可能会增加不必要的复杂性
  • 在这种情况下,使用简单的面向对象技术可能就足够了

2 ) 对性能有严格要求

  • 组合模式在处理复杂的对象树时可能会引入一些性能开销,因为需要在运行时遍历和操作这些对象
  • 如果应用程序对性能有非常严格的要求,那么可能需要避免使用组合模式,或者仔细评估其性能影响并采取相应的优化措施

3 ) 需要严格限制对象类型

  • 组合模式允许在对象树中组合不同类型的对象,这提供了很大的灵活性
  • 然而,在某些情况下,可能需要严格限制对象树中允许的对象类型
  • 使用组合模式可能会使这种类型限制变得更加复杂和难以维护
  • 在这种情况下,可能需要考虑使用其他设计模式或技术来实现类型限制

4 ) 不适合频繁变更的结构

  • 如果应用程序中的对象结构经常发生变化,那么使用组合模式可能会导致维护成本增加
  • 因为组合模式通常需要在多个类和方法中处理对象树的遍历和操作,当结构发生变化时,这些代码可能需要进行相应的修改和更新

5 ) 对接口有严格要求的场景

  • 在某些情况下,应用程序可能需要遵循特定的接口规范或协议,而这些规范可能不支持或不适合使用组合模式
  • 在这种情况下,可能需要考虑其他符合接口要求的设计模式或技术

6 ) 需要注意的是

  • 以上只是一些一般性的指导原则,并不适用于所有情况
  • 在实际应用中,是否使用组合模式需要根据具体的应用场景和需求进行权衡和决策
相关推荐
matrixlzp5 小时前
Java 责任链模式 减少 if else 实战案例
java·设计模式
编程、小哥哥7 小时前
设计模式之组合模式(营销差异化人群发券,决策树引擎搭建场景)
决策树·设计模式·组合模式
hxj..8 小时前
【设计模式】外观模式
java·设计模式·外观模式
吾与谁归in8 小时前
【C#设计模式(10)——装饰器模式(Decorator Pattern)】
设计模式·c#·装饰器模式
无敌岩雀10 小时前
C++设计模式行为模式———命令模式
c++·设计模式·命令模式
In_life 在生活19 小时前
设计模式(四)装饰器模式与命令模式
设计模式
瞎姬霸爱.20 小时前
设计模式-七个基本原则之一-接口隔离原则 + SpringBoot案例
设计模式·接口隔离原则
鬣主任21 小时前
Spring设计模式
java·spring boot·设计模式
程序员小海绵【vincewm】1 天前
【设计模式】结合Tomcat源码,分析外观模式/门面模式的特性和应用场景
设计模式·tomcat·源码·外观模式·1024程序员节·门面模式
丶白泽1 天前
重修设计模式-行为型-命令模式
设计模式·命令模式