2.5 、装饰模式的具体代码实现 刚开始一看这个“装饰模式”是有点不太好理解

时间:2021-10-21 06:31:07

原文:C#设计模式之八装饰模式(Decorator Pattern)【布局型】

一、引言

   今天我们要讲【布局型】设计模式的第三个模式,该模式是【装饰模式】,英文名称:Decorator Pattern。我第一次看到这个名称想到的是此外一个词语“装修”,我就说说我对“装修”的理解吧,大家必然要看清楚,是“装修”,不是“装饰”。我们长大了,就要成婚,要成婚就涉及到要买屋子,买的精装修或者简单装修就可以住的,暂时不谈。我们就谈谈我们采办的是毛坯房。如果我想要屋子的内饰是大理石气势派头的,我们只要在毛坯房的根本之上用大理石气势派头的质料装修就可以,我们固然不成能为了要一个装修气势派头,就把刚刚盖好的屋子拆了在从头来过。屋子装修好了,我们就住了进来,很高兴。过了段时间,我们发明我们的屋子在冬季对照冷,于是我就想给我们的屋子增加保暖的成果,装修好的屋子我们可以继续居住,我们只是在屋子外面加一层掩护层就可以了。又过了一段时间,总是有陌生人帮衬,所以我们想让屋子更安适,于是我们在外墙和房顶加装安适摄像头,同时门窗也增加安适系统。跟着时间的流逝,我们可能会按照我们的需求增加相应的成果,期间,我们的屋子可以正常使用,,加上什么设施就有了相应的成果。从这一方面来讲,“装修”和“装饰”有类似的观点,接下来就让我们看看装饰模式具体是什么吧!

二、装饰模式的详细介绍

2.1、动机(Motivate)

   在屋子装修的过程中,各类成果可以彼此组合,来增加屋子的服从。类似的,如果我们在软件系统中,要给某个类型或者东西增加成果,如果使用“担任”的方案来写代码,就会呈现子类暴涨的情况。好比:IMarbleStyle是大理石气势派头的一个成果,IKeepWarm是保温的一个接口界说,IHouseSecurity是屋子安适的一个接口,就三个接口来说,House是我们屋子,我们的屋子要什么成果就实现什么接口,如果屋子要的是复合成果,接口差此外组合就有差此外功效,这样就导致我们子类膨胀严重,如果需要在增加成果,子类会成指数增长。这个问题的泉源在于我们“过度地使用了担任来扩展东西的成果”,由于担任为类型引入的静态特质(所谓静态特质,就是说如果想要某种成果,我们必需在编译的时候就要界说这个类,这也是强类型语言的特点。静态,就是指在编译的时候要确定的对象;动态,是指运行时确定的对象),使得这种扩展方法缺乏灵活性;并且跟着子类的增多(扩展成果的增多),各类子类的组合(扩展成果的组合)会导致更多子类的膨胀(多担任)。如何使“东西成果的扩展”能够按照需要来动态(即运行时)地实现?同时制止“扩展成果的增多”带来的子类膨胀问题?从而使得任何“成果扩展变革”所导致的影响降为最低?

2.2、意图(Intent)

   动态地给一个东西增加一些特别的职责。就增加成果而言,Decorator模式比生成子类更为灵活。         ——  《设计模式》GoF

2.3、布局图(Structure)

      

2.5 、装饰模式的具体代码实现 刚开始一看这个“装饰模式”是有点不太好理解



2.4、模式的构成

    在装饰模式中的各个角色有:

  (1)、抽象构件角色(Component):给出一个抽象接口,以规范筹备接收附加责任的东西。

  (2)、具体构件角色(Concrete Component):界说一个将要接收附加责任的类。

  (3)、装饰角色(Decorator):持有一个构件(Component)东西的实例,并实现一个与抽象构件接口一致的接口。

  (4)、具体装饰角色(Concrete Decorator):卖力给构件东西添加上附加的责任。

2.5 、装饰模式的具体代码实现

   刚开始一看这个“装饰模式”是有点不太好理解,既然这个模式是面向东西的设计模式,那在现实生活中必然有事例和其对应,其实这种例子也不少,大家好好的挖掘吧,也可以提高我们劈面向东西的理解。我继续拿盖屋子来说事吧。
 

1 namespace 装饰模式的实现 2 { 3 /// <summary> 4 /// 该抽象类就是屋子抽象接口的界说,该类型就相当于是Component类型,是饺子馅,需要装饰的,需要包装的 5 /// </summary> 6 public abstract class House 7 { 8 //屋子的装修要领--该操纵相当于Component类型的Operation要领 9 public abstract void Renovation(); 10 } 11 12 /// <summary> 13 /// 该抽象类就是装饰接口的界说,该类型就相当于是Decorator类型,如果需要具体的成果,可以子类化该类型 14 /// </summary> 15 public abstract class DecorationStrategy:House //关键点之二,浮现关系为Is-a,有这这个关系,装饰的类也可以继续装饰了 16 { 17 //通过组合方法引用Decorator类型,该类型实施具体成果的增加 18 //这是关键点之一,包罗关系,浮现为Has-a 19 protected House _house; 20 21 //通过结构器注入,初始化平台实现 22 protected DecorationStrategy(House house) 23 { 24 this._house=house; 25 } 26 27 //该要领就相当于Decorator类型的Operation要领 28 public override void Renovation() 29 { 30 if(this._house!=null) 31 { 32 this._house.Renovation(); 33 } 34 } 35 } 36 37 /// <summary> 38 /// PatrickLiu的屋子,我要按我的要求做屋子,相当于ConcreteComponent类型,这就是我们具体的饺子馅,我小我私家对照喜欢韭菜馅 39 /// </summary> 40 public sealed class PatrickLiuHouse:House 41 { 42 public override void Renovation() 43 { 44 Console.WriteLine("装修PatrickLiu的屋子"); 45 } 46 } 47 48 49 /// <summary> 50 /// 具有安适成果的设备,可以供给监视和报警成果,相当于ConcreteDecoratorA类型 51 /// </summary> 52 public sealed class HouseSecurityDecorator:DecorationStrategy 53 { 54 public HouseSecurityDecorator(House house):base(house){} 55 56 public override void Renovation() 57 { 58 base.Renovation(); 59 Console.WriteLine("增加安适系统"); 60 } 61 } 62 63 /// <summary> 64 /// 具有保温接口的质料,供给保温成果,相当于ConcreteDecoratorB类型 65 /// </summary> 66 public sealed class KeepWarmDecorator:DecorationStrategy 67 { 68 public KeepWarmDecorator(House house):base(house){} 69 70 public override void Renovation() 71 { 72 base.Renovation(); 73 Console.WriteLine("增加保温的成果"); 74 } 75 } 76 77 public class Program 78 { 79 static void Main() 80 { 81 //这就是我们的饺子馅,需要装饰的屋子 82 House myselfHouse=new PatrickLiuHouse(); 83 84 DecorationStrategy securityHouse=new HouseSecurityDecorator(myselfHouse); 85 securityHouse.Renovation(); 86 //屋子就有了安适系统了 87 88 //如果我既要安适系统又要保暖呢,继续装饰就行 89 DecorationStrategy securityAndWarmHouse=new HouseSecurityDecorator(securityHouse); 90 securityAndWarmHouse.Renovation(); 91 } 92 } 93 }