【设计模式】组合模式

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

相关推荐
强化学习与机器人控制仿真22 分钟前
RSL-RL:开源人形机器人强化学习控制研究库
开发语言·人工智能·stm32·神经网络·机器人·强化学习·模仿学习
百***480729 分钟前
【Golang】slice切片
开发语言·算法·golang
q***925136 分钟前
Windows上安装Go并配置环境变量(图文步骤)
开发语言·windows·golang
仟濹1 小时前
【Java 基础】面向对象 - 继承
java·开发语言
郝学胜-神的一滴1 小时前
Linux命名管道:创建与原理详解
linux·运维·服务器·开发语言·c++·程序人生·个人开发
2501_941623321 小时前
C++高性能网络服务器与epoll实战分享:大规模并发连接处理与事件驱动优化经验
开发语言·php
晚风(●•σ )1 小时前
C++语言程序设计——11 C语言风格输入/输出函数
c语言·开发语言·c++
likuolei2 小时前
XML 元素 vs. 属性
xml·java·开发语言
X***48962 小时前
C源代码生成器
c语言·开发语言
梁正雄2 小时前
2、Python流程控制
开发语言·python