组合模式

1.定义

Compose objects into tree structures to represent part-whole hierarchies.Composite lets clients treat individual objects and compositions of objects uniformly.(将对象组合成树形结构以表示"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性。)

组合模式_第1张图片

Component抽象构件角色:定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性。

Leaf叶子构件:叶子对象,其下再也没有其他的分支,也就是遍历的最小单位。

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

2.通用代码

 1 namespace ConsoleApplication1
 2 {
 3     /// <summary>
 4     /// 抽象构件
 5     /// </summary>
 6     public abstract class Component
 7     {
 8         //抽象方法
 9         public abstract void DoSomeThing();
10     }
11 
12     /// <summary>
13     /// 树枝构件
14     /// </summary>
15     public class Composite : Component
16     {
17         private List<Component> _componentArrayList = new List<Component>();
18 
19         public void Add(Component c)
20         {
21             _componentArrayList.Add(c);
22         }
23 
24         public void Remove(Component c)
25         {
26             _componentArrayList.Remove(c);
27         }
28 
29         public List<Component> GetChildren()
30         {
31             return _componentArrayList;
32         }
33     }
34 
35     /// <summary>
36     /// 枝叶构件
37     /// </summary>
38     public class Leaf : Component
39     { }
40 
41     public class Client
42     {
43         public static void Main(string[] args)
44         {
45             Composite root = new Composite();
46 
47             Composite branch = new Composite();
48 
49             Leaf leaf = new Leaf();
50 
51             root.Add(branch);
52 
53             branch.Add(leaf);
54 
55             Console.ReadKey();
56 
57         }
58 
59         private static void Display(Composite root)
60         {
61             foreach (var item in root.GetChildren())
62             {
63                 if (item is Leaf)
64                 {
65                     item.DoSomeThing();
66                 }
67                 else
68                 {
69                     Display(item as Composite);
70                 }
71             }
72         }
73     }
74 
75 }

3.组合模式的缺点

组合模式有一个非常明显的缺点,看到我们在场景类中的定义,我们直接使用了树叶和树枝的具体实现类。这在面向接口编程上是很不恰当的,与依赖倒置原则冲突。

4.使用场景

  • 维护和展示部分-整体的场景,如树形菜单、文件和文件夹很容易。
  • 从一个整体中能够独立出部分模块或功能的场景。

5.模式的扩展

  • 透明的组合模式

    组合模式有两种不同的实现:透明模式和安全模式。我们上面讲的是安全模式,那么透明模式是怎样的呢?透明模式的通用类图如下所示:

    组合模式_第2张图片

    透明模式就是把用来组合使用的方法放到抽象类中,比如Add、Remove方法等。

     1 namespace ConsoleApplication1
     2 {
     3     /// <summary>
     4     /// 抽象构件
     5     /// </summary>
     6     public abstract class Component
     7     {
     8         private List<Component> _componentArrayList = new List<Component>();
     9 
    10         //抽象方法
    11         public abstract void DoSomeThing();
    12 
    13         public abstract void Add(Component c)
    14         {
    15             _componentArrayList.Add(c);
    16         }
    17 
    18         public abstract void Remove(Component c)
    19         {
    20             _componentArrayList.Remove(c);
    21         }
    22 
    23         public abstract List<Component> GetChildren()
    24         {
    25             return _componentArrayList;
    26         }
    27     }
    28 
    29     /// <summary>
    30     /// 树枝构件
    31     /// </summary>
    32     public class Composite : Component
    33     {
    34     }
    35 
    36     /// <summary>
    37     /// 枝叶构件
    38     /// </summary>
    39     public class Leaf : Component
    40     {
    41         public override void Add(Component c)
    42         {
    43             throw new NotSupportedException();
    44         }
    45 
    46         public override void Remove(Component c)
    47         {
    48             throw new NotSupportedException();
    49         }
    50 
    51         public override List<Component> GetChildren()
    52         {
    53             throw new NotSupportedException();
    54         }
    55     }
    56 
    57     public class Client
    58     {
    59         public static void Main(string[] args)
    60         {
    61             Composite root = new Composite();
    62 
    63             Composite branch = new Composite();
    64 
    65             Leaf leaf = new Leaf();
    66 
    67             root.Add(branch);
    68 
    69             branch.Add(leaf);
    70 
    71             Console.ReadKey();
    72 
    73         }
    74 
    75         private static void Display(Component root)
    76         {
    77             foreach (var item in root.GetChildren())
    78             {
    79                 if (item is Leaf)
    80                 {
    81                     item.DoSomeThing();
    82                 }
    83                 else
    84                 {
    85                     Display(item);
    86                 }
    87             }
    88         }
    89     }
    90 
    91 }
  • 从下向上遍历

     在Component抽象类中添加Parent属性,当调用Add()方法时,设置Parent的值。

 

你可能感兴趣的:(组合模式)