设计模式之组合模式(树形结构)

来源:互联网 发布:网络博客钱能追回来吗 编辑:程序博客网 时间:2024/06/05 23:41

举例:

北京总公司下有人力资源部和财务部,这两个部门正在使用一套软件,现在,总公司希望旗下分公司和办事处也都使用该套软件。

旗下分公司和办事处下也同样分忧人力资源部和财务部。该公司的结构如下图所示:

------北京总公司

-------------上海华东分公司

--------------------------南京办事处

--------------------------杭州办事处

-------------重庆西南分公司

--------------------------江北办事处

--------------------------江津办事处

1、上面这种树形结构就要使用到组合模式,首先创建一个公司抽象类

    /// <summary>
    /// 公司抽象类
    /// </summary>
    public abstract class Company
    {
        //公司名称
        protected string _name;
        public Company(string name)
        {
            _name = name;
        }

        //一定有的抽象方法
        //新增节点
        public abstract void Add(Company company);
        //移除节点
        public abstract void Remove(Company company);

        //自定义的方法
        //展示树结构
        public abstract void Display(int depth);
        //具体执行职责
        public abstract void ExecuteDuty();
    }

2、创建具体公司类(包含根节点和树枝节点

    /// <summary>
    /// 具体公司
    /// </summary>
    public class ConcreteCompany:Company
    {
        private List<Company> children = new List<Company>();
        public ConcreteCompany(string name)
            : base(name)
        {

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

        public override void Display(int depth)
        {
            Console.WriteLine(new String('-',depth)+_name);
            foreach (Company c in children)
            {
                c.Display(depth+2);
            }

        }
        public override void ExecuteDuty()
        {
            foreach (Company c in children)
            {
                c.ExecuteDuty();
            }

        }
    }

3、创建具体部门类(代表叶子节点,下面无子节点了

    /// <summary>
    /// 人力资源处(叶节点,无子节点)
    /// </summary>
    public class HRDepartment:Company
    {
        public HRDepartment(string name)
            : base(name)
        {

        }
        public override void Add(Company company) { }
        public override void Remove(Company company) { }
        public override void Display(int depth)
        {
            Console.WriteLine(new String('-',depth)+_name);
        }
        public override void ExecuteDuty()
        {
            Console.WriteLine("{0} 员工招聘培训管理",_name);
        }
    }
    /// <summary>
    /// 财务部(叶节点,无子节点)
    /// </summary>
    public class FinanceDepartment:Company
    {
        public FinanceDepartment(string name)
            : base(name)
        {

        }
        public override void Add(Company company) { }
        public override void Remove(Company company) { }
        public override void Display(int depth)
        {
            Console.WriteLine(new String('-',depth)+_name);
        }
        public override void ExecuteDuty()
        {
            Console.WriteLine("{0} 公司财务收支管理",_name);
        }
    }

4、客户端调用(注意节点分明)

           Company root = new ConcreteCompany("北京总公司");
            root.Add(new HRDepartment("总公司人力资源部"));
            root.Add(new FinanceDepartment("总公司财务部"));

            Company com1 = new ConcreteCompany("上海华东分公司");
            com1.Add(new HRDepartment("华东分公司人力资源部"));
            com1.Add(new FinanceDepartment("华东分公司财务部"));
            root.Add(com1);

            Company com2 = new ConcreteCompany("南京办事处");
            com2.Add(new HRDepartment("南京办事处人力资源部"));
            com2.Add(new FinanceDepartment("南京办事处财务部"));
            com1.Add(com2);

            Company com3 = new ConcreteCompany("杭州办事处");
            com2.Add(new HRDepartment("杭州办事处人力资源部"));
            com2.Add(new FinanceDepartment("杭州办事处财务部"));
            com1.Add(com3);

            Company com4 = new ConcreteCompany("重庆西南分公司");
            com4.Add(new HRDepartment("西南分公司人力资源部"));
            com4.Add(new FinanceDepartment("西南分公司财务部"));
            root.Add(com4);

            Company com5 = new ConcreteCompany("江北办事处");
            com5.Add(new HRDepartment("江北办事处人力资源部"));
            com5.Add(new FinanceDepartment("江北办事处财务部"));
            com4.Add(com5);

            Company com6 = new ConcreteCompany("江津办事处");
            com6.Add(new HRDepartment("江津办事处人力资源部"));
            com6.Add(new FinanceDepartment("江津办事处财务部"));
            com4.Add(com3);

            root.Display(1);

            root.ExecuteDuty();

5、总结

当你发现需求中是体现部分与整体层次的结构时,以及希望用户可以忽略组合对象和单个对象的不同,统一的使用组合结构中的所有对象时,就应该考虑组合模式了

0 0