C#设计模式之组合

IronMan之组合 

 

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

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

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

 1     public abstract class WeaponUpgradeLevel1

 2     {

 3         protected List<WeaponUpgradeLevel1> weaponUpgrades=new List<WeaponUpgradeLevel1>();

 4 

 5         public List<WeaponUpgradeLevel1> WeaponUpgrades

 6         {

 7             get

 8             {

 9                 return weaponUpgrades;

10             }

11 

12         }

13         /// <summary>

14         /// 判断是“部分”对象 还是 “整体”对象

15         /// </summary>

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         /// <summary>

31         /// 攻击

32         /// </summary>

33         public abstract void Attack();

34         /// <summary>

35         /// 添加    “部分”对象或者是“整体”对象      到“整体”对象

36         /// </summary>

37         /// <param name="weaponupgrade"></param>

38         /// <returns></returns>

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         /// <summary>

50         /// 从“整体”对象中移除 “部分”对象或者是“整体”对象

51         /// </summary>

52         /// <param name="weaponupgrade"></param>

53         /// <returns></returns>

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

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     public abstract class WeaponUpgradeLevel1

  2     {

  3         protected List<WeaponUpgradeLevel1> weaponUpgrades=new List<WeaponUpgradeLevel1>();

  4 

  5         public List<WeaponUpgradeLevel1> WeaponUpgrades

  6         {

  7             get

  8             {

  9                 return weaponUpgrades;

 10             }

 11 

 12         }

 13         /// <summary>

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

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

 16         /// </summary>

 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         /// <summary>

 32         /// 攻击

 33         /// </summary>

 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         /// <summary>

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

 54         /// </summary>

 55         /// <param name="weaponupgrade"></param>

 56         /// <returns></returns>

 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         /// <summary>

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

 69         /// </summary>

 70         /// <param name="weaponupgrade"></param>

 71         /// <returns></returns>

 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

C#设计模式之组合

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

 

作者:金源

出处:http://www.cnblogs.com/jin-yuan/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面

你可能感兴趣的:(设计模式)