设计模式(三)-结构型模式(4)-组合模式

一、为何需要组合模式(Composite)?

在代码设计中,有种情况是对象之间存在层次关系,即对象之间会存在父结点和子结点的关系。

比如在文件管理系统中,所有文件和文件夹形成树状结构,文件夹目录里存在子文件夹和文件。文件夹属于枝结点,文件属于叶结点。枝结点有下一个层级,所以可以对其子结点的对象进行移除或增加新对象的操作。而叶结点并没有移除和增加的操作,是因为它没有子结点。

对于这种对象之间存在的层级关系,我们可以使用组合模式来设计。

特点:

将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。(一致性:如文件夹和文件都有被打开的操作。所有文件夹对其子结点都有移除和增加新子结点的操作。)

结构:

组合对象的抽象接口(Component):定义组合对象的公共接口。(组合对象指的是所有结点。如文件系统的打开,移除和增加的功能接口)

叶结点具体类(Leaf):叶结点实现组合对象的抽象方法,但没有子结点。(如文件)

枝结点具体类(Composite):枝节点实现组合对象的抽象方法,并且有一个容器用来存储子结点。(如文件夹)

适合应用场景特点:

  • 对象之间存在层次结构,具有使用某些功能的一致性。

二、例子

需求:

一家公司里的部门有人事部、开发部、测试部、设计部。现在该公司又把测试部再分为软件测试组和硬件测试组。每个测试组都有一个组长。每当完成某个阶段任务时,公司要求每个部门以及测试部组长进行汇报工作进度的情况。

设计分析:

  • 枝结点:公司、人事部、开发部、设计部、测试部、软件测试组、硬件测试组。叶结点:软件测试组长和硬件测试组长。
  • 所有结点的公共动作:汇报工作。
  • 所有树枝结点都有增加和移除结点的操作。

1、定义组合对象的抽象接口:

c 复制代码
    //Component:(组合对象的抽象接口,叶结点抽象接口)
    public abstract class Company
    {
        public string Name { get; protected set; }
        public abstract void reportWork();
    }

    //Component:(组合对象的抽象接口,枝结点抽象接口)
    public abstract class AbsComposite : Company
    {
        public abstract void Add(Company company);
        public abstract void Remove(Company company);
    }

2、定义叶结点具体类和枝结点具体类:

c 复制代码
//Leaf:叶结点具体类(组长、同事成员)
    public class GroupLeader : Company
    {
        public GroupLeader(string name)
        {
            Name = name;
        }
        public override void reportWork()
        {
            Console.WriteLine(Name);
        }
    }

    //Composite:枝结点具体类(公司、部门)
    public class Composite : AbsComposite
    {
        private List<Company> _CompanyList = new List<Company>();//容器
        public List<Company> CompanyList { get { return _CompanyList; } }

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

        public override void Add(Company company)
        {
            _CompanyList.Add(company);
        }

        public override void Remove(Company company)
        {
            _CompanyList.Remove(company);
        }

        public override void reportWork()
        {
            Console.WriteLine("The following members need to report their work to our company:");
            getCompanyList(CompanyList);
        }

        //不是组合对象的公共接口,是 Department 类私有的成员方法。
        //该方法是为了测试例子而用的,并不是学习组合模式的要点。可忽略。
        private void getCompanyList(List<Company> list)
        {
            foreach (var item in list)
            {

                var itemDepart = item as Composite;//枝结点
                if (itemDepart != null)
                {
                    if (itemDepart.CompanyList?.Count > 0)
                    {
                        Console.WriteLine();
                        Console.Write("【" + item.Name +"】" + "-");枝结点,有子结点
                        getCompanyList(itemDepart.CompanyList);
                        continue;
                    }

                    Console.WriteLine("【" + item.Name + "】");//枝结点,子结点为空
                }
                else
                    Console.Write("(" + item.Name + ")");//叶结点

            }

        }

    }

3、主程序:

c 复制代码
    //主程序
    class Program
    {
        static void Main(string[] args)
        {
            AbsComposite root = new Composite("阳光组合公司");
            root.Add(new Composite("人事部"));
            root.Add(new Composite("开发部"));
            root.Add(new Composite("设计部"));
            
            var testDepartment = new Composite("测试部");
            var software = new Composite("软件测试组");
            var hardware = new Composite("硬件测试组");
            GroupLeader softwareLeader = new GroupLeader("软件测试组长");
            GroupLeader hardwareLeader = new GroupLeader("硬件测试组长");

            root.Add(testDepartment);
            testDepartment.Add(software);
            testDepartment.Add(hardware);
            software.Add(softwareLeader);
            hardware.Add(hardwareLeader);

            root.reportWork();//各部门和测试组长汇报工作

            Console.ReadLine();
        }
    }
相关推荐
Maddie_Mo23 分钟前
智能体设计模式 第二章:路由模式
设计模式
一条闲鱼_mytube4 小时前
智能体设计模式(五)人机协同-知识检索RAG-智能体间通信
网络·人工智能·设计模式
小码过河.4 小时前
设计模式——建造者模式
单片机·设计模式·建造者模式
小码过河.6 小时前
设计模式——工厂方法模式
设计模式·工厂方法模式
把csdn当日记本的菜鸡6 小时前
Java设计模式简单入门
java·开发语言·设计模式
老蒋每日coding6 小时前
AI Agent 设计模式系列(十一)—— 目标设定和监控模式
人工智能·设计模式·langchain
蔺太微7 小时前
外观模式(Facade Pattern)
设计模式·外观模式
进击的小头7 小时前
C语言实现设计模式的核心基石
c语言·开发语言·设计模式
Engineer邓祥浩7 小时前
设计模式学习(15) 23-13 模版方法模式
java·学习·设计模式
茶本无香7 小时前
设计模式之四:建造者模式(Builder Pattern)详解
java·设计模式·建造者模式