【设计模式】组合模式

组合模式(Composite Pattern)

概念:

· 是一种结构型设计模式;

· 将对象组合成树形结构,表示"整体-部分"的层次关系,使客户端可以对待单一对象和对象集合;

UML结构:

复制代码
           Component (抽象组件)
           -------------------
           + Operation()
           + Add(c)
           + Remove(c)
           + GetChild(i)
                |
        ----------------------
        |                    |
     Leaf (叶子节点)      Composite (组合节点)
     -----------------   ----------------------
     + Operation()       + Operation()
                         + Add(c)
                         + Remove(c)
                         + GetChild(i)
                         - children: List<Component>

代码示例:

cs 复制代码
/// <summary>
/// 文件系统抽象类
/// </summary>
public abstract class IFileSystemComponent
{
    // 以缩进形式打印目录结构
    public abstract void Display(int depth);

    // 获取当前组件的大小
    public abstract int GetSize();
}

/// <summary>
/// 具体文件实现类
/// </summary>
public class File : IFileSystemComponent
{
    public string Name { get; set; }
    public int Size { get; set; }
    public string FileFormat { get; set; }
    public File(string name, int size, string fileFormat)
    {
        this.Name = name;
        this.Size = size;
        this.FileFormat = fileFormat;
    }
    public void Display(int depth)
    {
        Console.WriteLine(new string(' ', depth * 2) + $"- {Name}.{FileFormat}({Size}KB)");
    }
    public int GetSize()
    {
        return Size;
    }
}

/// <summary>
/// 具体文件夹实现类
/// </summary>
public class Directory : IFileSystemComponent
{
    private List<IFileSystemComponent> _fileList = new(); // 文件列表
    public string Name { get; set; } // 文件名称
    public Directory(string name)
    {
        this.Name = name;
    }
    public void Display(int depth)
    {
        Console.WriteLine(new string(' ', depth * 2) + $"- {Name}");

        foreach (IFileSystemComponent file in _fileList)
        {
            file.Display(depth + 1);
        }
    }
    public int GetSize()
    {
        if (_fileList.Count <= 0) return 0;
        int total = 0;
        foreach (var child in _fileList)
        {
            total += child.GetSize();
        }
        return total;
    }
    public void Add(IFileSystemComponent component)
    {
        // 检查输入
        if (component != null) return;

        if (_fileList != null && !_fileList.Contains(component))
        {
            _fileList.Add(component);
        }
    }
    public void Remove(IFileSystemComponent component)
    {
        // 检查输入
        if (component != null) return;

        if (_fileList != null)
        {
            _fileList.Remove(component);
        }
    }
}

/// <summary>
/// 客户端
/// </summary>
public class Client
{
    public static void Main()
    {
        IFileSystemComponent root = new Directory("Root");

        IFileSystemComponent fileA = new File("File_A", 10, ".txt");
        IFileSystemComponent fileB = new File("File_B", 20, ".txt");
        IFileSystemComponent fileC = new File("File_C", 30, ".txt");
        IFileSystemComponent fileD = new File("File_C", 40, ".txt");

        IFileSystemComponent subDir1 = new Directory("SubDir_1");
        IFileSystemComponent subDir2 = new Directory("SubDir_2");

        subDir2.Add(fileD);
        subDir1.Add(fileC);
        subDir1.Add(subDir2);

        root.Add(fileA);
        root.Add(fileB);
        root.Add(subDir1);

        // 打印目录树
        root.Display(0);

        Console.WriteLine("总大小: " + root.GetSize());
    }
}

特点:
优点:

· 清晰表示树形结构 :非常适合"整体-部分"场景;

· 统一处理叶子和组合对象 :客户端无需区分,操作透明;

· 便于扩展 :增加新的叶子或组合节点无需修改客户端代码;
缺点:

· 设计可能过度透明 :客户端对组合和叶子统一处理,有时需要区分,可能导致不安全操作;

· 增加系统复杂性 :树形结构和递归调用增加理解和维护难度;

适用场景:

· 系统有 "整体-部分" 层次结构;

· 需要对 单个对象和组合对象进行统一操作;

· 客户端希望忽略对象组合的层次,直接操作组件;

举例场景:

· 文件系统;

· 公司组织架构:Leaf :普通员工,Composite:部门经理(包含下属员工列表);

· GUI 组件:Leaf :按钮、文本框,Composite:面板、窗口(包含多个组件);

相关推荐
.道阻且长.几秒前
Linux基本开发工具:gdb和cgdb的使用
linux·运维·服务器·开发语言
starzy199035 分钟前
深入理解Scala匿名函数:函数式编程基石
开发语言·scala
是2的10次方啊1 小时前
设计模式与生活⑯:天冷了,出门这身得一层层配
设计模式
apcipot_rain1 小时前
C++转Java日记(05)
java·开发语言·c++
apcipot_rain10 小时前
C++转Java日记(04)
java·开发语言·c++
云和数据.ChenGuang12 小时前
LangGraph 异步 Node 的设计与写法实践
开发语言·人工智能·python·机器学习·php
蜗牛一步步往上爬15 小时前
第十六章 C++语言在深度学习中的应用
开发语言·c++·深度学习
张张123y17 小时前
DSH 插件调试避坑:client.js 设置面板、热重载与高频报错排查表
开发语言·javascript·人工智能·开源·ecmascript·后端开发·ai agent
冻柠檬飞冰走茶20 小时前
字母移动游戏题解:贪心求最长可保留连续子串(附 C 实现)
c语言·开发语言·数据结构·算法·动态规划
心若自由何处是束缚20 小时前
适配器模式:从原理到实战的完整指南
设计模式·适配器模式