IronMan之组合

在上个篇幅中讲到怎么把“武器”装饰到“部件”上,这个篇幅呢,还是要讲到“武器”,不过呢是关于“武器”使用的。
本篇介绍"武器"的合理使用方式,不说废话,直接来看起初使用遇到的问题:
一起来看一下“武器”的定义:
1 public abstract class WeaponUpgradeLevel1
2 {
3 protected List weaponUpgrades=new List();
4
5 public List WeaponUpgrades
6 {
7 get
8 {
9 return weaponUpgrades;
10 }
11
12 }
13 ///
14 /// 判断是“部分”对象 还是 “整体”对象
15 ///
16 public bool IsSingle
17 {
18 get
19 {
20 if (weaponUpgrades.Count > 0)
21 {
22 return false;
23 }
24 else
25 {
26 return true;
27 }
28 }
29 }
30 ///
31 /// ***
32 ///
33 public abstract void Attack();
34 ///
35 /// 添加 “部分”对象或者是“整体”对象 到“整体”对象
36 ///
37 ///
38 ///
39 public virtual bool Add(WeaponUpgradeLevel1 weaponupgrade)
40 {
41 if (weaponupgrade != null)
42 {
43 WeaponUpgrades.Add(weaponupgrade);
44 return true;
45 }
46 else { return false; }
47
48 }
49 ///
50 /// 从“整体”对象中移除 “部分”对象或者是“整体”对象
51 ///
52 ///
53 ///
54 public virtual bool Remove(WeaponUpgradeLevel1 weaponupgrade)
55 {
56 if (weaponupgrade != null)
57 {
58 if (WeaponUpgrades.Contains(weaponupgrade))
59 {
60 WeaponUpgrades.Remove(weaponupgrade);
61 return true;
62 }
63 else
64 {
65 return false;
66 }
67 }
68 else { return false; }
69 }
70 }
71 public class Rocket : WeaponUpgradeLevel1
72 {
73 private string _name = "火箭炮";
74
75 public override void Attack()
76 {
77 Console.WriteLine("使用" + _name + "进行***");
78 }
79 }
80 public class RocketLevel1 : WeaponUpgradeLevel1
81 {
82 private string _name = "火箭炮(EX.2X2)";//由四个火箭炮组成
83
84 public override void Attack()
85 {
86 Console.WriteLine("使用"+_name+"进行***");
87 }
88 } 上面定义了三种类型,WeaponUpgradeLevel1是“武器”的抽象,并且在其中定义了一些属性和方法,
用于表示实现了此“武器”抽象的类型是否是核心武器(部分)还是核心武器的外壳(整体),
并且也在后面实现了“武器”抽象,分别是Rocket核心武器(部分)和RocketLevel1核心武器的外壳(整体),这样的结构定义好了过后,我们来看一下子,怎么使用它们:
1 WeaponUpgradeLevel1 weaRocket1 = new Rocket(); 2 WeaponUpgradeLevel1 weaRocket2 = new Rocket(); 3 WeaponUpgradeLevel1 weaRocket3 = new Rocket(); 4 WeaponUpgradeLevel1 weaRocket4 = new Rocket(); 5 6 WeaponUpgradeLevel1 weaRocketlevel1 = new RocketLevel1(); 7 weaRocketlevel1.Add(weaRocket1); 8 weaRocketlevel1.Add(weaRocket2); 9 weaRocketlevel1.Add(weaRocket3); 10 weaRocketlevel1.Add(weaRocket4);
这时候 weaRocketlevel1示例是像图1这样的:
图1

图2

要是使用weaRocketlevel1,真正的目的不是使用它本身,而是使用它里面的小火箭炮(也就是weaRocket1……)。 如果想要使用里面的小火箭炮,并不是简简单单的遍历一下就可以了,从现在的情况来看,确实是很简单的遍历
,获取到每个火箭炮,并且使用它们, 但是如果这个"火箭炮(EX.2X2)"改成了"火箭炮(EX.8X8)"呢? 并且"火箭炮(EX.8X8)"是由 4个"火箭炮(EX.4X4)"组成,每个"火箭炮(EX.4X4)"是由4个"火箭炮(EX.2X2)"组成的。 在这样的情况下怎么办? 没错了,是使用递归来遍历,然后的情况就是如图3所示:
图3

这样来看,也确实没什么大问题,只是耦合度比较高。
使用设计模式可以在特定的情况下解耦,这里的情况比较适合Composite模式。
将对象组合成树形结构以表示“部分-整体”的层次结构。Composite模式使得用户对单个对象和组合
对象的使用具有一致性。
[GOF 《设计模式》]
根据设计的中心思想,看一下修改后的结构:
1 public abstract class WeaponUpgradeLevel1
2 {
3 protected List weaponUpgrades=new List();
4
5 public List WeaponUpgrades
6 {
7 get
8 {
9 return weaponUpgrades;
10 }
11
12 }
13 ///
14 /// 判断是“部分”对象 还是 “整体”对象。
15 /// true为“部分”对象 反之相对
16 ///
17 public bool IsSingle
18 {
19 get
20 {
21 if (weaponUpgrades.Count > 0)
22 {
23 return false;
24 }
25 else
26 {
27 return true;
28 }
29 }
30 }
31 ///
32 /// ***
33 ///
34 public virtual void Attack()
35 {
36 ActionAttack(this);
37 }
38 private void ActionAttack(WeaponUpgradeLevel1 weaponupgrade)
39 {
40 if (weaponupgrade.IsSingle)
41 {
42 weaponupgrade.Attack();
43 }
44 else
45 {
46 foreach (WeaponUpgradeLevel1 weapon in weaponupgrade.WeaponUpgrades)
47 {
48 ActionAttack(weapon);
49 }
50 }
51 }
52 ///
53 /// 添加 “部分”对象或者是“整体”对象 到“整体”对象
54 ///
55 ///
56 ///
57 public virtual bool Add(WeaponUpgradeLevel1 weaponupgrade)
58 {
59 if (weaponupgrade != null)
60 {
61 WeaponUpgrades.Add(weaponupgrade);
62 return true;
63 }
64 else { return false; }
65
66 }
67 ///
68 /// 从“整体”对象中移除 “部分”对象或者是“整体”对象
69 ///
70 ///
71 ///
72 public virtual bool Remove(WeaponUpgradeLevel1 weaponupgrade)
73 {
74 if (weaponupgrade != null)
75 {
76 if (WeaponUpgrades.Contains(weaponupgrade))
77 {
78 WeaponUpgrades.Remove(weaponupgrade);
79 return true;
80 }
81 else
82 {
83 return false;
84 }
85 }
86 else { return false; }
87 }
88 }
89 public class Rocket : WeaponUpgradeLevel1
90 {
91 private string _name = "火箭炮";
92
93 public override void Attack()
94 {
95 Console.WriteLine("使用" + _name + "进行***");
96 }
97 }
98 public class RocketLevel1 : WeaponUpgradeLevel1
99 {
100 private string _name = "火箭炮(EX.2X2)";//由四个火箭炮组成
101
102 public override void Attack()
103 {
104 base.Attack();
105 Console.WriteLine("使用"+_name+"进行***");
106 }
107 } 看一下现在的客户端怎么使用“火箭炮”:
1 WeaponUpgradeLevel1 weaRocket1 = new Rocket(); 2 WeaponUpgradeLevel1 weaRocket2 = new Rocket(); 3 WeaponUpgradeLevel1 weaRocket3 = new Rocket(); 4 WeaponUpgradeLevel1 weaRocket4 = new Rocket(); 5 WeaponUpgradeLevel1 weaRocketlevel1 = new RocketLevel1(); 6 weaRocketlevel1.Add(weaRocket1); 7 weaRocketlevel1.Add(weaRocket2); 8 weaRocketlevel1.Add(weaRocket3); 9 weaRocketlevel1.Add(weaRocket4); 10 weaRocketlevel1.Attack();
所示结果如图4
图4

根据设计模式的思想修改代码的区别是在“武器”抽象中把对“核心武器”的使用做了统一的使用。意思就不做阐述了可以自己理解理解。
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
当前名称:C#设计模式之组合-创新互联
链接分享:http://www.jxjierui.cn/article/dsigje.html


咨询
建站咨询
