99、23种设计模式之组合模式(8/23)

组合模式(Composite Pattern)作为23种经典设计模式之一,属于结构型模式,其核心价值在于统一处理树形结构中的单个对象与组合对象,通过定义一致的接口,使客户端无需区分操作的是叶子节点还是分支节点。

一、组合模式的核心概念

1.适用场景

  • 需要表示"部分-整体"层次结构(如文件系统、UI组件、组织架构)。
  • 希望客户端统一处理单个对象和组合对象,避免冗余的条件判断。
  • 支持递归操作(如遍历树形结构)。

2.核心角色

  • Component(抽象组件):定义叶子节点和分支节点的公共接口,声明管理子节点的方法(如Add、Remove)。
  • Leaf(叶子节点):表示单个对象,无子节点,实现Component接口但抛出异常或空实现管理子节点的方法。
  • Composite(分支节点):包含子节点(叶子或分支),实现Component接口并管理子节点的增删查。

二、C#实现方式

组合模式在C#中有两种典型实现方式,各有优缺点:

1. 透明式组合模式

  • 特点:在Component抽象类中声明所有管理子节点的方法(如Add、Remove),叶子节点和分支节点均实现这些方法(叶子节点抛出异常)。
  • 优点:客户端可一致处理所有节点,无需区分类型。
  • 缺点:叶子节点实现无意义的方法,可能引发运行时异常。
csharp 复制代码
// 抽象组件
public abstract class Component
{
    public string Name { get; set; }
    public abstract void Add(Component component);
    public abstract void Remove(Component component);
    public abstract void Display(int depth);
}

// 叶子节点
public class Leaf : Component
{
    public Leaf(string name) => Name = name;
    public override void Add(Component component) => 
        throw new InvalidOperationException("Leaf cannot add components.");
    public override void Remove(Component component) => 
        throw new InvalidOperationException("Leaf cannot remove components.");
    public override void Display(int depth) => 
        Console.WriteLine($"{new string('-', depth)}{Name}");
}

// 分支节点
public class Composite : Component
{
    private List<Component> _children = new List<Component>();
    public Composite(string name) => Name = name;
    public override void Add(Component component) => _children.Add(component);
    public override void Remove(Component component) => _children.Remove(component);
    public override void Display(int depth)
    {
        Console.WriteLine($"{new string('-', depth)}{Name}");
        foreach (var child in _children) child.Display(depth + 2);
    }
}

// 客户端代码
var root = new Composite("Root");
root.Add(new Leaf("Leaf A"));
root.Add(new Leaf("Leaf B"));
var composite = new Composite("Composite X");
composite.Add(new Leaf("Leaf XA"));
root.Add(composite);
root.Display(1);

2. 安全式组合模式

  • 特点:Component仅声明通用方法(如Display),管理子节点的方法(如Add、Remove)仅在Composite中定义。
  • 优点:避免叶子节点实现无意义方法,类型安全。
  • 缺点:客户端需区分节点类型,破坏透明性。
csharp 复制代码
// 抽象组件(仅声明通用方法)
public abstract class Component
{
    public string Name { get; set; }
    public abstract void Display(int depth);
}

// 叶子节点
public class Leaf : Component
{
    public Leaf(string name) => Name = name;
    public override void Display(int depth) => 
        Console.WriteLine($"{new string('-', depth)}{Name}");
}

// 分支节点(声明管理子节点的方法)
public class Composite : Component
{
    private List<Component> _children = new List<Component>();
    public Composite(string name) => Name = name;
    public void Add(Component component) => _children.Add(component);
    public void Remove(Component component) => _children.Remove(component);
    public override void Display(int depth)
    {
        Console.WriteLine($"{new string('-', depth)}{Name}");
        foreach (var child in _children) child.Display(depth + 2);
    }
}

// 客户端需区分类型调用方法
var composite = new Composite("Composite");
composite.Add(new Leaf("Leaf")); // 合法
var leaf = new Leaf("Leaf");
leaf.Add(new Leaf("Leaf"));     // 编译错误(类型安全)

三、组合模式的优缺点

1.优点

  • 简化客户端代码:统一处理单个对象和组合对象,减少条件判断。
  • 扩展性强:新增组件类型(如新图形)无需修改现有代码,符合开闭原则。
  • 支持递归:方便遍历树形结构(如计算文件夹大小)。

2.缺点

  • 过度使用导致复杂度增加:非层次结构场景强行使用会适得其反。
  • 性能问题:大型树形结构的递归遍历可能引发栈溢出,需优化为迭代或缓存结果。

四、典型应用场景

  • 图形编辑器:基本图形(圆、矩形)与组合图形(由多个基本图形组成)的统一绘制。
  • 文件系统:文件与文件夹的统一操作(如删除、复制)。
  • UI组件:按钮、文本框等控件与窗口的统一管理。
  • 组织架构:员工与部门的统一权限控制。

五、与其他模式的对比

  • 与装饰器模式区别:装饰器模式动态添加职责,组合模式构建树形结构。
  • 与外观模式区别:外观模式简化复杂子系统调用,组合模式统一处理树形结构节点。
相关推荐
ttod_qzstudio18 小时前
【软考设计模式】备忘录模式:对象状态的捕获与无损恢复精讲
设计模式·备忘录模式
ttod_qzstudio19 小时前
【软考设计模式】责任链模式:请求传递的多级处理与发送接收解耦精讲
设计模式·责任链模式
2501_9142459319 小时前
C语言设计模式详解:从理论到实践的完整指南
c语言·开发语言·设计模式
CaffeinePro1 天前
四⼤极简架构原则KISS/DRY/YAGNI/LOD
设计模式·架构
霸道流氓气质1 天前
SpringBoot中设计模式组合使用示例-策略、模板、观察者、门面、工厂、单例。
spring boot·后端·设计模式
ttod_qzstudio1 天前
【软考设计模式】观察者模式:一对多依赖的自动通知与订阅解耦精讲
观察者模式·设计模式
ttod_qzstudio1 天前
【软考设计模式】命令模式:请求封装与调用接收解耦的精讲
设计模式·命令模式
春卷同学1 天前
HarmonyOS掌上记账APP开发实践第5篇:鸿蒙 EventBus 设计模式 — MoneyTrack 跨模块通信解密
华为·设计模式·harmonyos
春卷同学1 天前
HarmonyOS掌上记账APP开发实践第3篇:接口与实现分离 — MoneyTrack Types.ets 与 Models.ets 的双层设计模式
设计模式
NG4772 天前
【软件设计与体系结构】-策略设计模式
java·设计模式·软件工程