设计模式(10)----- 组合模式

ComPosite(组合)

关键词: 树

问题:

将对象组织成树形结构。【磁盘管理 公司组织】

意图:

将对象组合成树形结构以表示“部分-整体”的层次结构。
Composite使得用户对单个对象和组合对象的使用【具有一致性】。

适用性:

你想表示对象的部分-整体层次结构。
你希望用户忽略组合对象与单个对象的不同,
用户将统一地使用组合结构中的所有对象。

优点:

  1. 组合模式使得客户端代码可以一致地处理单个对象和组合对象,无须关心自己处理的是单个对象,还是组合对象,这简化了客户端代码;
  2. 更容易在组合体内加入新的对象,客户端不会因为加入了新的对象而更改源代码,满足“开闭原则”;

缺点:

  1. 设计较复杂,客户端需要花更多时间理清类之间的层次关系;
  2. 不容易限制容器中的构件;
  3. 不容易用继承的方法来增加构件的新功能;

组合模式包含以下主要角色。

抽象构件(Component)角色:

它的主要作用是为树叶构件和树枝构件声明公共接口,并实现它们的默认行为。在透明式的组合模式中抽象构件还声明访问和管理子类的接口;在安全式的组合模式中不声明访问和管理子类的接口,管理工作由树枝构件完成。(总的抽象类或接口,定义一些通用的方法,比如新增、删除)

树叶构件(Leaf)角色:

是组合中的叶节点对象,它没有子节点,用于继承或实现抽象构件。

树枝构件(Composite)角色 / 中间构件:

是组合中的分支节点对象,它有子节点,用于继承和实现抽象构件。它的主要作用是存储和管理子部件,通常包含 Add()、Remove()、GetChild() 等方法。

实现类图:
在这里插入图片描述
抽象构件(Component)角色:公司

public abstract class EmployeeBase//公司
{
    protected string strName;//人名
    public int salary;//工资
    //构造方法
    public EmployeeBase(string name, int salarys)
    {
        strName = name;
        this.salary = salarys;
    }
    //添加所管理的下属
    abstract public void Add(EmployeeBase c);
    //输出个人信息
    abstract public void DumpContents();
    //取出工资数
    virtual public int GetSalary()
    {
        return salary;
    }
}

树叶构件(Leaf)角色:管理人员

using System;
using System.Collections;

public class Manager : EmployeeBase//CEO   部门经理
{   //该管理人员管理下属
    private ArrayList employees = new ArrayList();
    //添加管理员工
    override public void Add(EmployeeBase c)
    {
        employees.Add(c);
    }
    //返回当前管理人员数
    public int Count
    {
        get { return employees.Count; }
    }
    //输出管理人员信息 和 所属下属人员信息
    public override void DumpContents()
    {
        Console.WriteLine("{0} 工资:" + salary, strName);
        foreach (EmployeeBase c in employees)
        {
            c.DumpContents();
        }
    }
    //得到下属对象  可能是管理人员 也可能是员工
    public EmployeeBase GetChild(int i)
    {
        return (EmployeeBase)employees[i];
    }
    public Manager(string s, int salary) : base(s, salary) { }
}

员工类

using System;

public class Employee : EmployeeBase//员工类
{
    public override void Add(EmployeeBase c){ }
    //输出个人信息
    public override void DumpContents()
    {
        Console.WriteLine("{0} 工资:" + salary, strName);
    }
    //构造方法
    public Employee(string s, int salary) : base(s, salary) { }
}

测试

using System;

class Program
{
    static void Main(string[] args)
    {   //初始化有9个员工  3个经理  1个CEO
        Employee e1 = new Employee("z1", 10000);
        Employee e2 = new Employee("z2", 10000);
        Employee e3 = new Employee("z3", 10000);
        Employee e4 = new Employee("z4", 10000);
        Employee e5 = new Employee("z5", 10000);
        Employee e6 = new Employee("z6", 10000);
        Employee e7 = new Employee("z7", 10000);
        Employee e8 = new Employee("z8", 10000);
        Employee e9 = new Employee("z9", 10000);

        Manager m1 = new Manager("m1 CEO", 40000);
        Manager m2 = new Manager("m2 市场", 20000);
        Manager m3 = new Manager("m2 研发", 30000);
        Manager m4 = new Manager("m2 客服", 20000);
        //CEO  管理  3个经理
        m1.Add(m2);
        m1.Add(m3);
        m1.Add(m4);
        //市场部经理管理 2个员工
        m2.Add(e1);
        m2.Add(e2);
        //研发部经理管理 5个员工
        m3.Add(e3);
        m3.Add(e4);
        m3.Add(e5);
        m3.Add(e6);
        m3.Add(e7);
        //客服部经理管理 2个员工
        m4.Add(e8);
        m4.Add(e9);

        //输出当前团队信息
        m1.DumpContents();
        //计算当前团队人员的总薪水
        var totalSalary = GetAllSalary(m1);
        Console.WriteLine("总计:" + totalSalary);

        Console.ReadLine();
    }
    //计算管理人员  包括下属  的工资总数
    public static int GetAllSalary(EmployeeBase emp)
    {
        var salary = emp.GetSalary();
        //判断当前传进来对象  是否是管理人员
        if (emp is Manager)
        {
            var mgr = emp as Manager;
            for (int i = 0; i < mgr.Count; i++)
            {
                salary += GetAllSalary(mgr.GetChild(i));
            }
        }
        return salary;
    }
}

输出示例
在这里插入图片描述
设计模式------首页

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值