设计模式-组合模式

设计模式-组合模式

定义:组合模式也叫部分-整体模式,将对象组合成树形结构以表示 “部分-整体” 的层次结构,使得用户对单个对象和组合对象的使用具有一致性。

一个公司的人员(部分员工)组成结构如下
在这里插入图片描述
如上的树形结构图展示了一个公司的人员结构,公司最高指挥者是CEO,往下一层是研发经理、销售经理、财务经理、人事部经理等等,根据部门不同,经理下还有组长,组长下还有具体员工。

从该属性结构分析,有两种不同的节点
组合节点:有子节点的节点 (如上 CEO、研发经理)
叶子节点:没有子节点的节点 (如上 研发组员 A,销售员F)

通过组合节点和子节点,能够无限递归迭代的拓扑树形结构。

组合模式的角色结构图如下
在这里插入图片描述
Component 抽象构件角色
定义组合对象的共有方法和属性,可以定义一些默认的行为或属性

Leaf 叶子构件
叶子对象,其下没有其他的分支,是最小的单元

Composite 树枝(组合)构件
树枝对象,它的作用是组合树枝节点和叶子节点形成一个树形结构

下面将公司员工结构通过代码实现
Component 抽象构件角色

    // 员工:Component 
    // 员工接口,抽象构件角色
    public interface IEmployee
    {
        string Info { get; set; }

        // 设置员工信息
        void SetInfo(string info);

        // 获取员工信息
        string GetInfo();

        // 工作
        void Working();
    }

Composite 树枝(组合)构件

    // 领导者:Composite 
    // 组合构件,可以添加组合构件、叶子构件作为子节点
    public class Leader : IEmployee
    {
        private List<IEmployee> employeeList = new List<IEmployee>();

        public void AddEmployee(IEmployee employee)
        {
            employeeList.Add(employee);
        }

        public void RemoveEmployee(IEmployee employee)
        {
            employeeList.Remove(employee);
        }

        public IEmployee GetEmployee(int index)
        {
            return employeeList[index];
        }

        public string Info { get; set; }

        // 员工信息
        public void SetInfo(string info)
        {
            Info = info;
        }

        // 获取员工信息
        public string GetInfo()
        {
            return Info;
        }

        // 工作
        public void Working()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(Info + string.Format(" 开始工作了我需要管理{0}个组员", employeeList.Count));
            foreach(var employee in employeeList)
            {
                sb.Append(employee.Info + "  ");
            }
            sb.AppendLine();
            sb.AppendLine();

            Console.WriteLine(sb.ToString());

            foreach(var employee in employeeList)
            {
                employee.Working();
            }
        }
    }

Leaf 叶子构件

    // 组员:Leaf 叶子构件
    // 不能添加叶子节点了
    public class Members : IEmployee
    {
        public string Info { get; set; }

        // 员工信息
        public void SetInfo(string info)
        {
            Info = info;
        }

        // 获取员工信息
        public string GetInfo()
        {
            return Info;
        }

        // 工作
        public void Working()
        {
            string msg = string.Format("{0} 开始工作了,我要认真完成我的工作 \n", Info);
            Console.WriteLine(msg);
        }
    }

代码调用如下

    class Corp
    {
        public Corp()
        {
            Leader ceo = new Leader();
            ceo.SetInfo("CEO");

            #region 研发部
            Leader developLeader = new Leader();
            developLeader.SetInfo("研发经理");

            Leader developGroup1 = new Leader();
            developGroup1.SetInfo("研发组长一");

            Leader developGroup2 = new Leader();
            developGroup2.SetInfo("研发组长二");

            Members develop1 = new Members();
            develop1.SetInfo("研发组员A");

            Members develop2 = new Members();
            develop2.SetInfo("研发组员B");

            Members develop3 = new Members();
            develop3.SetInfo("研发组员C");

            Members develop4 = new Members();
            develop4.SetInfo("研发组员D");

            Members develop5 = new Members();
            develop5.SetInfo("研发组员E");

            // 组合节点添加子节点
            // 将研发组长一、研发组长二 添加给 研发经理
            developLeader.AddEmployee(developGroup1);
            developLeader.AddEmployee(developGroup2);

            // 将研发组员A、研发组员B、研发组员C 添加给 研发组长一
            developGroup1.AddEmployee(develop1);
            developGroup1.AddEmployee(develop2);
            developGroup1.AddEmployee(develop3);

            // 将研发组员D、研发组员E、 添加给 研发组长二
            developGroup2.AddEmployee(develop4);
            developGroup2.AddEmployee(develop5);
            #endregion

            #region 销售部
            Leader saleLeader = new Leader();
            saleLeader.SetInfo("销售经理");

            Members sale1 = new Members();
            sale1.SetInfo("销售员F");

            Members sale2 = new Members();
            sale2.SetInfo("销售员G");

            Members sale3 = new Members();
            sale3.SetInfo("销售员H");

            // 将 销售员F、销售员G、销售员H 添加给 销售经理
            saleLeader.AddEmployee(sale1);
            saleLeader.AddEmployee(sale2);
            saleLeader.AddEmployee(sale3);
            #endregion

            // 将 研发经理、销售经理 添加给 CEO
            ceo.AddEmployee(developLeader);
            ceo.AddEmployee(saleLeader);

            // CEO 号召大家一起工作啦
            ceo.Working();
        }
    }

CEO 是整棵树的跟节点,运行时只需要调用 跟节点的执行方法 Working() 就可以调动整棵树所有节点的执行。

运行结果如下
在这里插入图片描述
如果结构比较复杂,可以使用配置文件动态的创建树形结构

优点:
(1)高层模块调用简单,一棵树的所有节点都是 Component,局部和整体对调用者来说没有任何区别,也就是说,高层模块不必关心自己处理的是单个对象还是整个组合结构,简化了高层模块的代码
(2)节点自由添加、删除,容易扩展,符合开闭原则,易于维护

缺点:
(1) 设计变得更加抽象,对象的业务规则如果比较复杂,则实现组合模式难度比较大

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值