LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

C# 实现组合模式的 3 种方式

admin
2025年6月13日 21:43 本文热度 50

前言

嗨,程序员小伙伴们,早上好!

今天跟大家分享设计模式中的组合模式,以及在 C# 中实现组合模式的 3 种方式。

话不多说,直接上正文。

核心思想

组合模式的核心思想是通过统一接口来处理单个对象(叶子节点)和对象组合(容器节点),使得客户端无需关心操作的是单个对象还是组合对象。

结构

  1. 抽象组件(Component) :定义一个接口,表示单个对象或组合对象的公共行为。
  2. 叶子组件(Leaf) :实现抽象组件接口,表示叶子节点,没有子节点。
  3. 组合组件(Composite) :实现抽象组件接口,表示组合节点,可以包含多个子节点。
  4. 客户端代码:通过统一的接口操作单个对象和组合对象,隐藏内部结构。

如下图:


经典继承方式

using System;
using System.Collections.Generic;

// 组件抽象类或接口
public abstract class Component
{
    protected string name;

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

    // 添加子组件
    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) : base(name)
    {
    }

    public override void Add(Component component)
    {
        // 叶子节点不能添加子组件
        Console.WriteLine("Cannot add to a leaf");
    }

    public override void Remove(Component component)
    {
        // 叶子节点不能移除子组件
        Console.WriteLine("Cannot remove from a leaf");
    }

    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) : base(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 (Component component in children)
        {
            component.Display(depth + 2);
        }
    }
}

// 使用
class Program
{
    static void Main(string[] args)
    {
        // 创建树结构
        Composite root = new Composite("Root");
        root.Add(new Leaf("Leaf A"));
        root.Add(new Leaf("Leaf B"));

        Composite comp = new Composite("Composite X");
        comp.Add(new Leaf("Leaf XA"));
        comp.Add(new Leaf("Leaf XB"));

        root.Add(comp);
        root.Add(new Leaf("Leaf C"));

        // 添加和移除叶子节点
        Leaf leaf = new Leaf("Leaf D");
        root.Add(leaf);
        root.Remove(leaf);

        // 递归显示树结构
        root.Display(1);
    }
}

2. 接口实现方式

using System;
using System.Collections.Generic;

// 组件接口
public interface IGraphic
{
    void Draw();
    void Add(IGraphic graphic);
    void Remove(IGraphic graphic);
    IGraphic GetChild(int index);
}

// 叶子节点实现
public class Circle : IGraphic
{
    public void Draw()
    {
        Console.WriteLine("Drawing a circle");
    }

    public void Add(IGraphic graphic)
    {
        throw new NotImplementedException();
    }

    public void Remove(IGraphic graphic)
    {
        throw new NotImplementedException();
    }

    public IGraphic GetChild(int index)
    {
        throw new NotImplementedException();
    }
}

// 复合图形实现
public class Picture : IGraphic
{
    private List<IGraphic> graphics = new List<IGraphic>();

    public void Draw()
    {
        Console.WriteLine("Drawing a picture containing:");
        foreach (var graphic in graphics)
        {
            graphic.Draw();
        }
    }

    public void Add(IGraphic graphic)
    {
        graphics.Add(graphic);
    }

    public void Remove(IGraphic graphic)
    {
        graphics.Remove(graphic);
    }

    public IGraphic GetChild(int index)
    {
        return graphics[index];
    }
}

// 使用
class Program
{
    static void Main(string[] args)
    {
        // 创建复合图形
        Picture picture = new Picture();

        // 添加简单图形
        picture.Add(new Circle());
        picture.Add(new Circle());

        // 创建另一个复合图形
        Picture innerPicture = new Picture();
        innerPicture.Add(new Circle());

        // 添加到主图形中
        picture.Add(innerPicture);

        // 绘制整个图形结构
        picture.Draw();
    }
}

3. 泛型方式实现

using System;
using System.Collections.Generic;

// 通用组件接口
public interface IComponent<Twhere T : IComponent<T>
{
    string Name { get; }
    void Add(T component);
    void Remove(T component);
    void Display(int depth);
}

// 叶子节点实现
public class Leaf : IComponent<Leaf>
{
    public string Name { get; }

    public Leaf(string name)
    {
        Name = name;
    }

    public void Add(Leaf component)
    {
        throw new InvalidOperationException("Cannot add to a leaf");
    }

    public void Remove(Leaf component)
    {
        throw new InvalidOperationException("Cannot remove from a leaf");
    }

    public void Display(int depth)
    {
        Console.WriteLine($"{new string('-', depth)}{Name}");
    }
}

// 复合组件实现
public class Composite : IComponent<Composite>
{
    private readonly List<Composite> children = new List<Composite>();
    public string Name { get; }

    public Composite(string name)
    {
        Name = name;
    }

    public void Add(Composite component)
    {
        children.Add(component);
    }

    public void Remove(Composite component)
    {
        children.Remove(component);
    }

    public void Display(int depth)
    {
        Console.WriteLine($"{new string('-', depth)}{Name}");

        foreach (var child in children)
        {
            child.Display(depth + 2);
        }
    }
}

// 使用示例
class Program
{
    static void Main(string[] args)
    {
        var root = new Composite("Root");
        var branch1 = new Composite("Branch 1");
        var branch2 = new Composite("Branch 2");

        branch1.Add(new Composite("Sub-branch 1.1"));
        branch1.Add(new Composite("Sub-branch 1.2"));

        branch2.Add(new Composite("Sub-branch 2.1"));

        root.Add(branch1);
        root.Add(branch2);

        root.Display(1);
    }
}

总结

经典继承方式 使用抽象基类定义组件公共接口,它结构清晰但不够灵活,新增操作需要修改基类,比较适合简单明确的层次结构。

接口实现方式 使用接口而非抽象类,支持多接口实现,更灵活,适合作为公共API的一部分。

泛型实现方式 可以创建类型特化的组件,支持更复杂的组件关系,但相应地灵活性更差,实现复杂度较高。

建议优先考虑接口实现方式,除非有特殊需求。


阅读原文:原文链接


该文章在 2025/6/14 16:51:45 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved