C#学习笔记-组合模式


什么是组合模式?

   组合模式(Composite):将对象组合成树形结构以表示“部分-整体”的层次结构。

               组合模式使得用户对单个对象和组合对象的使用具有一致性。

何时使用组合模式?

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

组合模式的组成

  Component():组合中的对象声明接口,在适当情况下,实现所有类共有接口的默认行为。

        声明一个接口用于访问和管理Component的子部件。

  Leaf():在组合中表示叶节点对象,叶节点没有子节点。

  Composite():定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关的操作,比如增加Add和删除Remove

组合模式具体实现

组合模式的结构

组合模式的实现:

Component():

 1         abstract class Component
 2         {
 3             protected string name;
 4             public Component(string name)
 5             {
 6                 this.name = name;
 7             }
 8             public abstract void Add(Component c);
 9             public abstract void Remove(Component c);
10             public abstract void Diaplay(int depth);
11         }

Leaf():

 1        class Leaf : Component
 2         {
 3             public Leaf(string name) : base(name)
 4             { }
 5 
 6             public override void Add(Component c)
 7             {
 8                 Console.WriteLine("Cannot add a leaf");
 9             }
10 
11             public override void Diaplay(int depth)
12             {
13                 Console.WriteLine(new String('-', depth) + name);
14             }
15 
16             public override void Remove(Component c)
17             {
18                 Console.WriteLine("Cannot remove from a leaf");
19             }
20         }

Composite():

 1         class Composite : Component
 2         {
 3             private List children = new List();
 4             public Composite(string name) : base(name)
 5             { }
 6 
 7             public override void Add(Component c)
 8             {
 9                 children.Add(c);
10             }
11 
12             public override void Diaplay(int depth)
13             {
14                 //将 System.String 类的新实例初始化为由重复指定次数的指定 Unicode 字符指示的值
15                 Console.WriteLine(new String('-', depth) + name);
16                 foreach(Component component in children)
17                 {
18                     component.Diaplay(depth + 2);
19                 }
20             }
21 
22             public override void Remove(Component c)
23             {
24                 children.Remove(c);
25             }
26         }

 主函数调用:

 1        static void Main(string[] args)
 2         {
 3             Composite root = new Composite("root");
 4             root.Add(new Leaf("Leaf A"));
 5             root.Add(new Leaf("Leaf B"));
 6 
 7             Composite comp = new Composite("Composite X");
 8             comp.Add(new Leaf("Leaf XA"));
 9             comp.Add(new Leaf("Leaf XB"));
10 
11             root.Add(comp);
12 
13             Composite comp2 = new Composite("Composite XY");
14             comp2.Add(new Leaf("Leaf XYA"));
15             comp2.Add(new Leaf("Leaf XYB"));
16 
17             comp.Add(comp2);
18 
19             root.Add(new Leaf("Leaf C"));
20 
21             Leaf leaf = new Leaf("Leaf D");
22             root.Add(leaf);
23             root.Remove(leaf);
24 
25             root.Diaplay(1);
26 
27             Console.Read();
28         }

 实现效果:

实例解析

   为了深化理解,我们准备一个具体的实例来分析。

分析:

具体实现:

  1     class Program
  2     {
  3         static void Main(string[] args)
  4         {
  5             ConcreteCompany root = new ConcreteCompany("北京公司总部");
  6             root.Add(new HRDepartment("北京公司总部人力资源部"));
  7             root.Add(new FinanceDepartment("北京公司总部财务部"));
  8 
  9             ConcreteCompany com = new ConcreteCompany("上海分公司");
 10             com.Add(new HRDepartment("上海分公司人力资源部"));
 11             com.Add(new FinanceDepartment("上海分公司财务部"));
 12 
 13             root.Add(com);
 14 
 15             ConcreteCompany com2 = new ConcreteCompany("南京办事处");
 16             com2.Add(new HRDepartment("南京办事处人力资源部"));
 17             com2.Add(new FinanceDepartment("南京办事处财务部"));
 18 
 19             com.Add(com2);
 20 
 21             ConcreteCompany com3 = new ConcreteCompany("杭州办事处");
 22             com3.Add(new HRDepartment("杭州办事处人力资源部"));
 23             com3.Add(new FinanceDepartment("杭州办事处财务部"));
 24             com.Add(com3);
 25 
 26             Console.WriteLine("\n结构图:");
 27             root.Diaplay(1);
 28 
 29             Console.WriteLine("\n职责:");
 30             root.LineOfDuty();
 31             Console.Read();
 32         }
 33     }
 34     abstract class Company
 35     {
 36         protected string name;
 37         public Company(string name)
 38         {
 39             this.name = name;
 40         }
 41         public abstract void Add(Company c);
 42         public abstract void Remove(Company c);
 43         public abstract void Diaplay(int depth);
 44         public abstract void LineOfDuty();
 45     }
 46     class ConcreteCompany : Company
 47     {
 48         private List children = new List();
 49         public ConcreteCompany(string name) : base(name)
 50         { }
 51 
 52         public override void Add(Company c)
 53         {
 54             children.Add(c);
 55         }
 56 
 57         public override void Diaplay(int depth)
 58         {
 59             Console.WriteLine(new String('-', depth) + name);
 60             foreach(Company company in children)
 61             {
 62                 company.Diaplay(depth + 2);
 63             }
 64         }
 65 
 66         public override void LineOfDuty()
 67         {
 68             foreach(Company component in children)
 69             {
 70                 component.LineOfDuty();
 71             }
 72         }
 73 
 74         public override void Remove(Company c)
 75         {
 76             children.Remove(c);
 77         }
 78     }
 79     class HRDepartment : Company
 80     {
 81         public HRDepartment(string name) : base(name)
 82         {
 83         }
 84 
 85         public override void Add(Company c)
 86         { }
 87 
 88         public override void Diaplay(int depth)
 89         {
 90             Console.WriteLine(new String('-', depth) + name);
 91         }
 92 
 93         public override void LineOfDuty()
 94         { Console.WriteLine("{0} 员工招聘培训管理", name); }
 95 
 96         public override void Remove(Company c)
 97         { }
 98     }
 99     class FinanceDepartment : Company
100     {
101         public FinanceDepartment(string name) : base(name)
102         { }
103 
104         public override void Add(Company c)
105         { }
106 
107         public override void Diaplay(int depth)
108         {
109             Console.WriteLine(new String('-', depth) + name);
110         }
111 
112         public override void LineOfDuty()
113         {
114             Console.WriteLine("{0} 公司财务收支管理", name);
115         }
116 
117         public override void Remove(Company c)
118         { }
119     }

备注:文中所有代码及知识点均来自于《大话设计模式》,本人属于边学边看边敲代码边总结的阶段。