C#设计模式之装饰者

IronMan之装饰者

前言

上一篇的文章我们讲到要给"IronMan"配备"武器",并且还使用了"武器",效果还是不错的,对于多种环境、多种攻击方式的"武器"使用,我们已经掌握了。 有的朋友没有看过上一篇文章,那也没关系,此篇的重点不会涉及到上一篇的内容。

好吧,废话不多说,直接进入正题, 这里简要的介绍下,本人一直在为一家"玩具厂"服务,致力于"IronMan"(钢铁侠)的研究,前面的几个篇幅都是在介绍怎么去合理的生产组成"IronMan"的"部件",以及最近需求的变更,需要"部件"可携带武器,并且能攻击,于是在上一篇中讲到了"武器"的使用,感兴趣的朋友可以去看看。 那我们要如何的去把"武器"和"部件"整合在一起呢?

问题的发现

先来看一下本篇篇幅要用到的一些"部件"和"武器"的结构, 部件的:

 1     public abstract class Component
 2     {
 3        ///之间的代码于本篇幅无关
 4        private string strName = string.Empty;
 5         /// <summary>
 6         /// 名称
 7         /// </summary>
 8         public string Name
 9         {
10             get { return strName; }
11             set { strName = value; }
12         }
13         /// <summary>
14         /// 自我描述
15         /// </summary>
16         public abstract void Self_Described();
17     }
18     public class RightHandComponent : Component
19     {
20         public RightHandComponent() : this("毅代先锋号一代右部件") { }
21         public RightHandComponent(string strname)
22         {
23             base.Name = strname;

24         }
25         public override void Self_Described()
26         {
27             Console.WriteLine("自描述:我是->" + base.Name);
28         }
29     }
30     public class LeftHandComponent : Component
31     {
32         public LeftHandComponent() : this("毅代先锋号一代左部件") { }
33         public LeftHandComponent(string strname)
34         {
35             base.Name = strname;
36         }
37         public override void Self_Described()
38         {
39             Console.WriteLine("自描述:我是->" + base.Name);
40         }
41     }

武器的:
(这里的结构经过简化,跟上个篇幅没有联系,感兴趣的朋友可以按照上个篇幅的"武器"结构来设计)

 1     /// <summary>
 2     /// 武器
 3     /// </summary>
 4     public abstract class Weapon
 5     {
 6         /// <summary>
 7         /// 攻击
 8         /// </summary>
 9         public abstract void Attack();
10     }
11     /// <summary>
12     /// 激光武器
13     /// </summary>
14     public class LaserWeapon : Weapon
15     {
16         public override void Attack()
17         {
18             //LaserAttack
19             Console.WriteLine("激光武器");
20         }
21     }
22     /// <summary>
23     /// 导弹武器
24     /// </summary>
25     public class MissileWeapon : Weapon
26     {
27         public override void Attack()
28         {
29             //MissileAttack
30             Console.WriteLine("导弹武器");
31         }
32     }

看到这样的结构,会想说怎么去为"部件"提供额外的功能呢?让各种武器继承自"部件"?N种武器怎么办?那"部件"的结构是多么大啊!!!想一下都觉得可怕。

问题的解决

不过还好,有设计模式的存在,在这种特定的情况下首先想到的就是"装饰者"模式。 旧版的"部件"和"武器"已经满足不了现在的需求了(可以满足,但是这样整合起来显得过于复杂和庞大,对于初学者可能不太容易学习,所以这里这样说)。 我们重新来升级"部件"和"武器"的结构:

 1     /// <summary>
 2     /// 新升级的武器规范
 3     /// </summary>
 4     public interface IWeaponUpgrade
 5     {
 6         /// <summary>
 7         /// 是武器了,当然要具备攻击性了,不然也不叫武器
 8         /// </summary>
 9         void Attack();
10     }
11     /// <summary>
12     /// 新升级的部件 支持携带武器(因为已经支持携带了武器,它自然而然的也归纳与武器一类)
13     /// 此部件为简化版(便于学习)——。
14     /// </summary>
15     public class ComUpgrade:IWeaponUpgrade
16     {
17         public void Attack()
18         {
19             Console.WriteLine("IronMan的某部件开始输出攻击:");
20         }
21     }

所以这里的"部件"也就是"武器"了,因为"部件"是被动武器,它自身并没有攻击能力,它需要安装主动性的武器(也就是需要给它装饰上真正具有攻击性的武器),
那我们再来看一下主动性攻击武器的结构:

 1     /// <summary>
 2     /// 武器包装器,主动性攻击武器要实现。功能:可以塞入任何武器类型,并且使得塞入的武器获得此武器(可是实现了此类的子类)的功能
 3     /// </summary>
 4     public class WeaponDecorator : IWeaponUpgrade
 5     {
 6         protected IWeaponUpgrade weaponUpgrade;
 7         public WeaponDecorator(IWeaponUpgrade weapon)
 8         {
 9             this.weaponUpgrade = weapon;
10         }
11         public virtual void Attack()
12         {
13             this.weaponUpgrade.Attack();
14         }
15     }
16     /// <summary>
17     /// 匕首
18     /// </summary>
19     public class Knife : WeaponDecorator
20     {
21         public Knife(IWeaponUpgrade weapon)
22             : base(weapon)
23         { }
24         public override void Attack()
25         {
26             base.Attack();
27             Console.WriteLine("匕首攻击");
28         }
29     }
30     /// <summary>
31     /// 锤子
32     /// </summary>
33     public class Hammer : WeaponDecorator
34     {
35         public Hammer(IWeaponUpgrade weapon)
36             : base(weapon)
37         { }
38         public override void Attack()
39         {
40             base.Attack();
41             Console.WriteLine("锤子攻击");
42         }
43     }

要使用的结构都定义好了,现在来看一下使用的情况:

1 ComUpgrade comupgrade = new ComUpgrade();
2 Knife knife = new Knife(comupgrade);
3 Hammer hammer = new Hammer(knife);
4 hammer.Attack();

看一下结果 图1

这样的结构就是比较完美的了,"部件"(也就是被动武器)的变化或者是装饰武器(主动性武器)的变化两者间是不会受影响的,可以随便新增新的"武器"到"部件"上,而且装饰武器之间也是可以相互装饰的,对于扩展"部件"的功能,这种方式比继承漂亮多了。细心的人会发现,还有跟装饰的顺序有关系,是这样的。 对于功能的扩展或许体现不出来装饰顺序的优美,但是在业务流程的需求里就能体现了,这一点就好比是那种业务链,比如是:网上商场的业务,选择商品->加入购物车->付款(这里只是举例),这样的一条业务,也可以是 选择商品->付款,是的,都是可以直接付款的,这里就可以把“加入购物车”、“付款”定义为装饰者对象,可以把用户信息定义为被装饰者,可以是“加入购物车”然后再“付款”,也可是直接“付款”,想想看这样用装饰者模式是不是很简单的就实现了。

END

作者:金源

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

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

时间: 2024-10-06 16:22:27

C#设计模式之装饰者的相关文章

设计模式 2 —— 装饰者模式

设计模式目录: 设计模式 1 ——观察者模式 设计模式 2 —— 装饰者模式

设计模式 之 装饰者

装饰模式(Deocrator)           动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活. 所谓装饰,就是一些对象给主题对象做陪衬.我们可以想象,在一个公司里面,每个人都有一个办工作,办工作都需要有电脑.电话.文件夹.盆栽.签字笔.公章等作为装饰.但是不同的人的办公桌上的装饰肯定不一样.比如说,老总的办公桌上应该什么都有,但是一般工作人员的办公桌上,就不应该有电话和公章.我们怎么动态的来装饰办公桌呢? using System; using System

Design Pattern 设计模式 Decorator 装饰者模式

1 设计一个基类 2 继承这个基类,并包含这个基类的一个对象 3 创建继承类的时候,初始化这个基类,因为是基类指针,所以可以是所有基类的衍生类对象,那么就可以叠加任意多个衍生类对象了. 关键是在衍生类中包含一个基类对象,然后有了继承和包含两重关系,可以使得一个类一个类对象叠加,达到装饰目的. 等于是创建了一个对象指针链表,一个一个对象发挥其相应的作用. 下面程序装饰一个桌子,同时包含释放内存的处理. 关键要知道基类的析构函数必须使用虚函数,为什么? 1 如果基类不是析构函数,那么如果衍生类中包含

java设计模式之 装饰器模式

适AT java设计模式之 装饰器模式 装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构. 这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,动态给一个对象添提供了额外的功能. 我们通过下面的实例来演示装饰器模式的用法.模拟一个人从想吃饭.找饭店.享受美食.结束吃饭的过程 代码展示: 首先创建一个被修饰的接口 Eat package deco

设计模式之装饰者模式(Decorator)

1.定义 装饰者模式动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案 2.类图 Component抽象构件:Component是一个接口或者是抽象类,就是定义我们最核心的对象,也就是最原始的对象.在装饰者模式中,必然有一个最基本.最核心.最原始的接口或抽象类充当Component抽象构件. ConcreteComponent具体构件:ConcreteComponent是最核心.最原始.最基本的接口或抽象类的实现,你要装饰的就是它. Decorator装饰角色:一般是一

设计模式之装饰者模式(三)

欢迎大家的持续关注.上一次,我们结合第一篇推导出来的类图,到第二篇根据类图进行实际代码的编写,对装饰者模式有了一个整体的概念以及实战.不知道对你帮助如何呢?小编已经有门道了,看完接下来的一部分,你会恍然大悟,原来实际编码中你一直在用装饰者模式. 真实世界的装饰者:Java I/O 看到标题,是不是就很想往下看,到底是I/O中的什么呢,让你早已经拥有了装饰者模式的实践?就如书上给的描述,你第一次(还有第二次和第三次)看到这些API发出"哇"的惊叹时,放心,你不是唯一收到惊吓的人.下面,我

掌握设计模式之装饰者模式

![](http://ww4.sinaimg.cn/large/006tNc79ly1g4ztauvhzej30p00dw45p.jpg) ## 前言 当应用开发中,我们要为一个对象在原有功能上进行扩展增强时,往往采用继承的方式,而继承过多时就会使得功能类更加复杂,不利于维护,而设计模式中装饰者模式可以帮助我们更好对应这种场景,装饰者模式可以做到让对象能够动态地进行功能扩展,而不影响其他对象. 那究竟它是如何实现的呢,又如何实际应用呢,就让我们一起来学习下这个模式吧. ## 模式定义 装饰者模式

java_设计模式_装饰者模式_Decorator Pattern(2016-07-28)

装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰模式的结构 装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任.换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同.装饰模式可以在不使用创造更多子类的情况下,将对象的功能加以扩展. 装饰模式的类图如下: 在装饰模式中的角色有: ● 抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象. ● 具体构件(ConcreteComponent)角色

设计模式之装饰者模式

设计模式系列都是学习HeadFirst设计模式得出的学习心得,中间的例子也会采用书中的例子.这里有必要解释一下,在下面星巴克咖啡的例子中,有几种基本的咖啡,还有牛奶.豆浆等等可以向咖啡中添加,这里说明防止下面不懂. 今天我们来了解一下装饰者模式. 回想一下java的io包,各种stream排上倒海,初学者根本分不清楚到底怎么用,眼花缭乱.其实,它的实验遵循了装饰者设计模式.顾名思义,装饰者就可以简单的理解成用一个东西来装饰另一个东西.比如,你要做鱼吃,在你做好出国之后需要加入香菜.我们就可以简单

python设计模式之装饰器模式

装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能. import time def log_calls(func): def wrapper(*args,**kwargs): now=time.time() print("Calling{0} with {1} and {2}