【设计模式】组合模式

组合模式(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:面板、窗口(包含多个组件);

相关推荐
!停几秒前
数据在内存中的存储(2)
开发语言·c++·算法
龙山云仓几秒前
No098:黄道婆&AI:智能的工艺革新与技术传承
大数据·开发语言·人工智能·python·机器学习
是喵斯特ya4 分钟前
python开发web暴力破解工具(基础篇)
开发语言·python·web安全
Legendary_0087 分钟前
Type-C一拖三快充线的核心优势与LDR6020方案深度解析
c语言·开发语言·电脑
MarkHD12 分钟前
智能体在车联网中的应用:第12天 CARLA实战:编写Python客户端生成与控制车辆,迈向联合仿真
开发语言·python
青出于兰13 分钟前
C语言| 指针变量的自增运算
c语言·开发语言
冷崖14 分钟前
原型模式-创建型
设计模式·原型模式
Poetinthedusk14 分钟前
设计模式-单例模式
单例模式·设计模式
有味道的男人16 分钟前
Python 爬虫框架设计:类封装与工程化实践
开发语言·爬虫·python
Davina_yu17 分钟前
R语言报错:无法打开文件‘sales_2025.txt‘: No such file or directory
开发语言·r语言