天天看点

C#设计模式之组合

IronMan之组合 

在上个篇幅中讲到怎么把“武器”装饰到“部件”上,这个篇幅呢,还是要讲到“武器”,不过呢是关于“武器”使用的。

本篇介绍"武器"的合理使用方式,不说废话,直接来看起初使用遇到的问题:

一起来看一下“武器”的定义:

上面定义了三种类型,WeaponUpgradeLevel1是“武器”的抽象,并且在其中定义了一些属性和方法,

用于表示实现了此“武器”抽象的类型是否是核心武器(部分)还是核心武器的外壳(整体),

并且也在后面实现了“武器”抽象,分别是Rocket核心武器(部分)和RocketLevel1核心武器的外壳(整体),这样的结构定义好了过后,我们来看一下子,怎么使用它们:

这时候 weaRocketlevel1示例是像图1这样的:

图1

C#设计模式之组合

图2

C#设计模式之组合

要是使用weaRocketlevel1,真正的目的不是使用它本身,而是使用它里面的小火箭炮(也就是weaRocket1……)。 如果想要使用里面的小火箭炮,并不是简简单单的遍历一下就可以了,从现在的情况来看,确实是很简单的遍历

,获取到每个火箭炮,并且使用它们, 但是如果这个"火箭炮(EX.2X2)"改成了"火箭炮(EX.8X8)"呢? 并且"火箭炮(EX.8X8)"是由 4个"火箭炮(EX.4X4)"组成,每个"火箭炮(EX.4X4)"是由4个"火箭炮(EX.2X2)"组成的。 在这样的情况下怎么办? 没错了,是使用递归来遍历,然后的情况就是如图3所示:

图3

C#设计模式之组合

这样来看,也确实没什么大问题,只是耦合度比较高。

使用设计模式可以在特定的情况下解耦,这里的情况比较适合Composite模式。

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

对象的使用具有一致性。                                                                                               

                [GOF 《设计模式》]

根据设计的中心思想,看一下修改后的结构:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

<code>  </code><code>1     </code><code>public</code> <code>abstract</code> <code>class</code> <code>WeaponUpgradeLevel1  </code>

<code>  </code><code>2     {  </code>

<code>  </code><code>3         </code><code>protected</code> <code>List&lt;WeaponUpgradeLevel1&gt; weaponUpgrades=</code><code>new</code> <code>List&lt;WeaponUpgradeLevel1&gt;();  </code>

<code>  </code><code>4   </code>

<code>  </code><code>5         </code><code>public</code> <code>List&lt;WeaponUpgradeLevel1&gt; WeaponUpgrades  </code>

<code>  </code><code>6         {  </code>

<code>  </code><code>7             </code><code>get</code>  

<code>  </code><code>8             {  </code>

<code>  </code><code>9                 </code><code>return</code> <code>weaponUpgrades; </code>

<code>  </code><code>10             } </code>

<code>  </code><code>11  </code>

<code>  </code><code>12         } </code>

<code>  </code><code>13         </code><code>/// &lt;summary&gt; </code>

<code>  </code><code>14         </code><code>/// 判断是“部分”对象 还是 “整体”对象。 </code>

<code>  </code><code>15         </code><code>/// true为“部分”对象 反之相对 </code>

<code>  </code><code>16         </code><code>/// &lt;/summary&gt; </code>

<code>  </code><code>17         </code><code>public</code> <code>bool</code> <code>IsSingle </code>

<code>  </code><code>18         { </code>

<code>  </code><code>19             </code><code>get</code> 

<code>  </code><code>20             { </code>

<code>  </code><code>21                 </code><code>if</code> <code>(weaponUpgrades.Count &gt; 0) </code>

<code>  </code><code>22                 { </code>

<code>  </code><code>23                     </code><code>return</code> <code>false</code><code>; </code>

<code>  </code><code>24                 } </code>

<code>  </code><code>25                 </code><code>else</code> 

<code>  </code><code>26                 { </code>

<code>  </code><code>27                     </code><code>return</code> <code>true</code><code>; </code>

<code>  </code><code>28                 } </code>

<code>  </code><code>29             } </code>

<code>  </code><code>30         } </code>

<code>  </code><code>31         </code><code>/// &lt;summary&gt; </code>

<code>  </code><code>32         </code><code>/// 攻击 </code>

<code>33         </code><code>/// &lt;/summary&gt; </code>

<code>34         </code><code>public</code> <code>virtual</code> <code>void</code> <code>Attack() </code>

<code>35         { </code>

<code>36             ActionAttack(</code><code>this</code><code>); </code>

<code>37         } </code>

<code>38         </code><code>private</code> <code>void</code> <code>ActionAttack(WeaponUpgradeLevel1 weaponupgrade) </code>

<code>39         { </code>

<code>40             </code><code>if</code> <code>(weaponupgrade.IsSingle) </code>

<code>41             { </code>

<code>42                 weaponupgrade.Attack(); </code>

<code>43             } </code>

<code>44             </code><code>else</code> 

<code>45             { </code>

<code>46                 </code><code>foreach</code> <code>(WeaponUpgradeLevel1 weapon </code><code>in</code> <code>weaponupgrade.WeaponUpgrades) </code>

<code>47                 { </code>

<code>48                     ActionAttack(weapon); </code>

<code>49                 } </code>

<code>50             } </code>

<code>51         } </code>

<code>52         </code><code>/// &lt;summary&gt; </code>

<code>53         </code><code>/// 添加    “部分”对象或者是“整体”对象      到“整体”对象 </code>

<code>54         </code><code>/// &lt;/summary&gt; </code>

<code>55         </code><code>/// &lt;param name="weaponupgrade"&gt;&lt;/param&gt; </code>

<code>56         </code><code>/// &lt;returns&gt;&lt;/returns&gt; </code>

<code>57         </code><code>public</code> <code>virtual</code> <code>bool</code> <code>Add(WeaponUpgradeLevel1 weaponupgrade) </code>

<code>58         { </code>

<code>59             </code><code>if</code> <code>(weaponupgrade != </code><code>null</code><code>) </code>

<code>60             { </code>

<code>61                 WeaponUpgrades.Add(weaponupgrade); </code>

<code>62                 </code><code>return</code> <code>true</code><code>; </code>

<code>63             } </code>

<code>64             </code><code>else</code> <code>{ </code><code>return</code> <code>false</code><code>; } </code>

<code>65  </code>

<code>66         } </code>

<code>67         </code><code>/// &lt;summary&gt; </code>

<code>68         </code><code>/// 从“整体”对象中移除 “部分”对象或者是“整体”对象 </code>

<code>69         </code><code>/// &lt;/summary&gt; </code>

<code>70         </code><code>/// &lt;param name="weaponupgrade"&gt;&lt;/param&gt; </code>

<code>71         </code><code>/// &lt;returns&gt;&lt;/returns&gt; </code>

<code>72         </code><code>public</code> <code>virtual</code> <code>bool</code> <code>Remove(WeaponUpgradeLevel1 weaponupgrade) </code>

<code>73         { </code>

<code>74             </code><code>if</code> <code>(weaponupgrade != </code><code>null</code><code>) </code>

<code>75             { </code>

<code>76                 </code><code>if</code> <code>(WeaponUpgrades.Contains(weaponupgrade)) </code>

<code>77                 { </code>

<code>78                     WeaponUpgrades.Remove(weaponupgrade); </code>

<code>79                     </code><code>return</code> <code>true</code><code>; </code>

<code>80                 } </code>

<code>81                 </code><code>else</code> 

<code>82                 { </code>

<code>83                     </code><code>return</code> <code>false</code><code>; </code>

<code>84                 } </code>

<code>85             } </code>

<code>86             </code><code>else</code> <code>{ </code><code>return</code> <code>false</code><code>; } </code>

<code>87         } </code>

<code>88     } </code>

<code>89     </code><code>public</code> <code>class</code> <code>Rocket : WeaponUpgradeLevel1 </code>

<code>90     { </code>

<code>91         </code><code>private</code> <code>string</code> <code>_name = </code><code>"火箭炮"</code><code>; </code>

<code>92  </code>

<code>93         </code><code>public</code> <code>override</code> <code>void</code> <code>Attack() </code>

<code>94         { </code>

<code>95             Console.WriteLine(</code><code>"使用"</code> <code>+ _name + </code><code>"进行攻击"</code><code>); </code>

<code>96         } </code>

<code>97     } </code>

<code>98     </code><code>public</code> <code>class</code> <code>RocketLevel1 : WeaponUpgradeLevel1 </code>

<code>99     {</code>

<code>100         </code><code>private</code> <code>string</code> <code>_name = </code><code>"火箭炮(EX.2X2)"</code><code>;</code><code>//由四个火箭炮组成</code>

<code>101 </code>

<code>102         </code><code>public</code> <code>override</code> <code>void</code> <code>Attack()</code>

<code>103         {</code>

<code>104            </code><code>base</code><code>.Attack();</code>

<code>105            Console.WriteLine(</code><code>"使用"</code><code>+_name+</code><code>"进行攻击"</code><code>);</code>

<code>106         }</code>

<code>107     }</code>

看一下现在的客户端怎么使用“火箭炮”:

所示结果如图4

图4

C#设计模式之组合

根据设计模式的思想修改代码的区别是在“武器”抽象中把对“核心武器”的使用做了统一的使用。意思就不做阐述了可以自己理解理解。

     本文转自jinyuan0829 51CTO博客,原文链接:http://blog.51cto.com/jinyuan/1418956,如需转载请自行联系原作者