天天看點

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,如需轉載請自行聯系原作者