Composite Pattern(组合模式)

模式简介

       组合模式是一种结构型设计模式,用于将节点及节点容器看作统一的节点对象,使得调用者无需关注是单个节点还是一组节点,只需要通过接口方法直接调用即可。最直观的和最常见的例子就是文件系统,文件系统中的文件夹和文件都看作是文件系统节点,文件夹下面可以包括文件和文件夹,这种树形层次的文件结构就是对组合模式的一种应用。

       常见的应用场景:文件系统、菜单系统、GUI界面布局等。

模式结构

  1. Component(组件):声明了组合中对象的接口,可以是一个抽象类或接口,其中定义了一些用于管理子对象的方法,如添加、删除、获取子对象等。

  2. Leaf(叶子):是组合中的叶子节点对象,它没有子对象。实现了组件接口,但是在叶子节点中,这些方法可能是空的实现或抛出异常。

  3. Composite(容器):是包含子对象的容器节点对象,它通常会实现组件接口的方法,并包含一个集合用于存储子对象。

  4. Client(客户端):通过组件接口与组合中的对象进行交互,不需要知道是处理叶子节点还是容器节点,从而可以统一处理整体和部分。

工作原理

  1. 统一接口:组合模式的核心思想是将叶子节点和容器节点都视为组件,它们都实现了相同的接口,这样客户端可以一致地对待单个对象和对象的组合。

  2. 递归组合:容器节点内部包含了子对象,这些子对象可以是叶子节点,也可以是容器节点,从而形成了一个递归的结构。

  3. 透明性:在透明组合模式中,客户端不需要判断当前处理的是叶子还是容器,直接通过组件接口进行操作。在安全组合模式中,客户端需要进行类型检查来确定如何操作。

  4. 简化客户端代码:通过组合模式,客户端代码不再需要关心处理的是单个对象还是对象的组合,简化了客户端代码,提高了系统的灵活性和可维护性。

代码示例(C#)

提示:可在本栏目的资源篇“设计模式代码示例合集”下载所有完整代码资源。

文件系统节点:FileSystemNode.cs


namespace CompositePattern;

// 文件系统节点
abstract class FileSystemNode
{
    protected string name; // 名称

    public FileSystemNode(string name)
    {
        this.name = name;
    }

    // 显示,level代表文件系统节点所在层级,根节点为1,根节点的一级子节点则为2,依次类推
    public abstract void Show(int level);
}

// 文件
class File : FileSystemNode
{
    public File(string name) : base(name) { }

    public override void Show(int level)
    {
        Console.WriteLine(new string('-', level) + name);
    }
}

// 文件夹
class Directory : FileSystemNode
{
    private List<FileSystemNode> fileSystemNodes; // 文件系统节点集合

    public Directory(string name) : base(name)
    {
        fileSystemNodes = new List<FileSystemNode>();
    }

    // 添加文件系统节点
    public void Add(FileSystemNode fileSystemNode)
    {
        fileSystemNodes.Add(fileSystemNode);
    }

    // 移除文件系统节点
    public void Remove(FileSystemNode fileSystemNode)
    {
        fileSystemNodes.Remove(fileSystemNode);
    }

    public override void Show(int level)
    {
        Console.WriteLine(new string('-', level) + name);
        for (int i = 0; i < fileSystemNodes.Count; i++)
        {
            fileSystemNodes[i].Show(level + 1);
        }
    }
}

测试代码:Program.cs

// ************* 11.组合模式测试 **************
// 创建三个文件和两个文件夹
CompositePattern.File fileA = new CompositePattern.File("文件A");
CompositePattern.File fileB = new CompositePattern.File("文件B");
CompositePattern.File fileC = new CompositePattern.File("文件C");
CompositePattern.Directory directoryA = new CompositePattern.Directory("文件夹A");
CompositePattern.Directory directoryB = new CompositePattern.Directory("文件夹B");

// 文件夹B中包含文件A和文件C
directoryB.Add(fileA);
directoryB.Add(fileC);

// 文件夹A中包含文件B和文件夹B
directoryA.Add(fileB);
directoryA.Add(directoryB);

// 显示文件夹A及其目录下的所有子文件夹和子文件
directoryA.Show(1);

代码解说

       上述代码简单模拟了文件系统中文件夹和文件的层次结构。文件夹和文件都继承自文件系统节点类,文件夹作为文件系统节点的容器。文件夹A下包含文件B和文件夹B,文件夹B下包含文件A和文件C。通过组合模式简化了调用逻辑,并提升了该文件系统的可扩展性,降低了维护成本,例如未来需要加入一种加密型文件夹,那么就可以直接让其继承文件系统节点类,而不需要去修改文件系统的源代码。

如果这篇文章对你有帮助,请给作者点个赞吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值