博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#设计模式之组合
阅读量:7083 次
发布时间:2019-06-28

本文共 7182 字,大约阅读时间需要 23 分钟。

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 IsSingle17 {18 get19 {20 if (weaponUpgrades.Count > 0)21 {22 return false;23 }24 else25 {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 else64 {65 return false;66 }67 }68 else { return false; }69 }70 }71 public class Rocket : WeaponUpgradeLevel172 {73 private string _name = "火箭炮";74 75 public override void Attack()76 {77 Console.WriteLine("使用" + _name + "进行攻击");78 }79 }80 public class RocketLevel1 : WeaponUpgradeLevel181 {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

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

 

作者:

出处:

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

转载于:https://www.cnblogs.com/jin-yuan/p/3735740.html

你可能感兴趣的文章
十分钟了解HTTPS
查看>>
如何培养良好的编程实践
查看>>
SAP HANA Hint简介
查看>>
前端教程之插件和类库封装
查看>>
《Android艺术开发探索》学习笔记之View的工作原理
查看>>
[译] Story 中 Type Mode 在 iOS 和 Android 上的实现
查看>>
全球银行网站成黑客主攻目标 阿里云提供安全防御应急方案
查看>>
Flutter完整项目-笑话Flutter(原创)
查看>>
数据结构与算法-表达式二叉树
查看>>
JavaSE基础:字符串
查看>>
iOS开发 __func__的使用
查看>>
iOS开发 使用fui(Find Unused Imports)扫描工程中不用的类
查看>>
Android组件化专题-路由动态注入跳转参数以及获取其他模块的fragment
查看>>
JavaScript中的执行机制
查看>>
WWDC2017-Customized Loading in WKWebView
查看>>
今天我才学会iOS的MVP写法
查看>>
Vue.js项目中管理每个页面的头部标签的方法
查看>>
function-表达式(内含自执行函数)
查看>>
2.字符串
查看>>
用Python从Unicode转换到中文并输出到文件
查看>>