zoukankan      html  css  js  c++  java
  • Net设计模式实例之组合模式(Composite Pattern)

    一、组合模式简介(Brief Introduction

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

     

    二、解决的问题(What To Solve

    解决整合与部分可以被一致对待问题。

    三、组合模式分析(Analysis

    1、组合模式结构

    Component类:组合中的对象声明接口,在适当情况下,实现所有类共有接口的行为。声明一个接口用于访问和管理Component的子部件

    Leaf类:叶节点对象,叶节点没有子节点。由于叶节点不能增加分支和树叶,所以叶节点的AddRemove没有实际意义。

    有叶节点行为,用来存储叶节点集合

    Composite类:实现Componet的相关操作,比如AddRemove操作。

    children:用来存储叶节点集合

    2、源代码

    1、抽象类Component

    public abstract class Component

    {

        protected string name;

     

        public Component(string name)

        {

            this.name = name;

        }

     

        public abstract void Add(Component c);

        public abstract void Remove(Component c);

        public abstract void Diaplay(int depth);

    }

     

    2、叶子节点Leaf 继承于Component

    public class Leaf:Component

    {

     

        public Leaf(string name)

            :base(name)

        {

           

        }

     

        public override void Add(Component c)

        {

            Console.WriteLine("不能向叶子节点添加子节点");

        }

     

        public override void Remove(Component c)

        {

            Console.WriteLine("叶子节点没有子节点");

        }

     

        public override void Diaplay(int depth)

        {

            Console.WriteLine(new string('-',depth)+name);

        }

    }

     

    3、组合类Composite继承于Component拥有枝节点行为

    public class Composite : Component

    {

     

        List<Component> children;

     

        public Composite(string name)

            :base(name)

        {

            if (children == null)

            {

                children = new List<Component>();

            }

        }

     

        public override void Add(Component c)

        {

            this.children.Add(c);

        }

     

        public override void Remove(Component c)

        {

            this.children.Remove(c);

        }

     

        public override void Diaplay(int depth)

        {

            Console.WriteLine(new String('-',depth)+name);

            foreach (Component component in children)

            {

                component.Diaplay(depth + 2);

            }

        }

    }

     

     

    4、客户端代码

    static void Main(string[] args)

    {

        Composite root = new Composite("根节点root");

        root.Add(new Leaf("根上生出的叶子A"));

        root.Add(new Leaf("根上生出的叶子B"));

     

        Composite comp = new Composite("根上生出的分支CompositeX");

        comp.Add(new Leaf("分支CompositeX生出的叶子LeafXA"));

        comp.Add(new Leaf("分支CompositeX生出的叶子LeafXB"));

     

        root.Add(comp);

     

        Composite comp2 = new Composite("分支CompositeX生出的分支CompositeXY");

        comp2.Add(new Leaf("分支CompositeXY生出叶子LeafXYA"));

        comp2.Add(new Leaf("分支CompositeXY生出叶子LeafXYB"));

     

        comp.Add(comp2);

     

        root.Add(new Leaf("根节点生成的叶子LeafC"));

        Leaf leafD = new Leaf("leaf D");

        root.Add(leafD);

        root.Remove(leafD);

        root.Diaplay(1);

        Console.Read();

    }

    3、程序运行结果

    四.案例分析(Example

    1、场景

    假设公司组织结构为:

    --总结理

    ----技术部门经理

    ------开发人员A

    ------开发人员B

    ----销售部门经理

    总经理直接领导技术部经理和销售部经理,技术部经理直接领导开发人员A和开发人员B。销售部经理暂时没有直接下属员工,随着公司规模增大,销售部门会新增销售员工。计算组织结构的总工资状况。

    如下图所示

    IComponent接口:此接口包括了ComponentComposite的所有属性,公司每个角色都有职称Title和工资待遇SalaryAdd方法把员工加入到组织团队中。

    Component叶子节点:叶节点没有子节点,Add方法实现没有任何意义。

    Composite组合类:此类有一个员工集合_listEmployees,Add方法向此集合中添加员工信息。

    GetCost方法获得组织结构中的工资待遇总和

    2、代码

    1、接口IComponent

    1. public interface IComponent   
    2.     {   
    3.         string Title { getset; }   
    4.         decimal Salary { getset; }   
    5.         void Add(IComponent c);   
    6.         void GetCost(ref decimal salary);   
    7.     }   

    8.    

     

    2、叶节点Component 

    1. public class Component : IComponent   
    2.     {   
    3.         public string Title { getset; }   
    4.         public decimal Salary { getset; }   
    5.   
    6.         public Component(string Title, decimal Salary)   
    7.         {   
    8.             this.Title = Title;   
    9.             this.Salary = Salary;   
    10.         }   
    11.   
    12.         public void Add(IComponent c)   
    13.         {   
    14.             Console.WriteLine("Cannot add to the leaf!");   
    15.         }   
    16.   
    17.         public void GetCost(ref decimal salary)   
    18.         {   
    19.             salary += Salary;   
    20.         }   
    21.     }   

    22.    

     

     

    3、组合类Composite 

    1.   public class Composite : IComponent   

    2.       {   

    3.           private List<IComponent> _listEmployees;   

    4.     

    5.           public string Title { getset; }   

    6.           public decimal Salary { getset; }   

    7.     

    8.           public Composite(string Title, decimal Salary)   

    9.           {   

    10.               this.Title = Title;   

    11.               this.Salary = Salary;   

    12.               _listEmployees = new List<IComponent>();   

    13.           }   

    14.     

    15.           public void Add(IComponent comp)   

    16.           {   

    17.               _listEmployees.Add(comp);   

    18.           }   

    19.     

    20.           public void GetCost(ref decimal salary)   

    21.           {   

    22.               salary += this.Salary;   

    23.     

    24.               foreach (IComponent component in this._listEmployees)   

    25.               {   

    26.                   component.GetCost(ref salary);   

    27.               }   

    28.           }   

    29.       }   

     

     

    4、客户端代码

    1. static void Main(string[] args)   
    2.         {   
    3.             decimal costCEO = 0.0M;   
    4.             decimal costVPD = 0.0M;   
    5.   
    6.             //Create CEO Node   
    7.             IComponent compCEO = new Composite("CEO", 500000);   
    8.   
    9.             //Create VP-Development and Developer nodes   
    10.             IComponent compVPDev = new Composite("VP-Development", 250000);   
    11.   
    12.             IComponent compDev1 = new Component("Developer1", 75000);   
    13.             IComponent compDev2 = new Component("Developer2", 50000);   
    14.   
    15.             compVPDev.Add(compDev1);   
    16.             compVPDev.Add(compDev2);   
    17.   
    18.             //Create VP-Sales node   
    19.             IComponent compVPSales = new Component("VP-Sales", 300000);   
    20.   
    21.             compCEO.Add(compVPDev);   
    22.             compCEO.Add(compVPSales);   
    23.   
    24.             //Get the cost incurred at the CEO level   
    25.             compCEO.GetCost(ref costCEO);   
    26.   
    27.             Console.WriteLine(String.Format("The Cost incurred at the CEO            level is {0:c} ", costCEO));   
    28.   
    29.             //Get the cost incurred at the VP-Development level   
    30.             compVPDev.GetCost(ref costVPD);   
    31.             Console.WriteLine(String.Format("The Cost incurred at the VP-Development level is {0:c} ", costVPD));   
    32.         }   

    33.    

     

    五、总结(Summary

    组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。解决整合与部分可以被一致对待问题。

  • 相关阅读:
    C# RabbitMQ
    使用HttpClient和WebRequest时POST一个对象的写法
    HTTP中application/x-www-form-urlencoded字符说明
    MVC5 Entity Framework学习
    SQL Server安全
    Entity Framework查询
    COM 类工厂中 CLSID 为 {000209FF-0000-0000-C000-000000000046} 的组件失败,原因是出现以下错误: 80070005 拒绝访问。最新解决方案
    js中精度问题以及解决方案
    string.format
    t-sql对被除数为0&除数小于被除数结果为0&除法保留2位小数的处理
  • 原文地址:https://www.cnblogs.com/ywqu/p/1650351.html
Copyright © 2011-2022 走看看