第8章 装饰模式(Decorator Pattern)

原文 第8章
装饰模式(Decorator Pattern)

概述:

装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

装饰模式的特点:

(1)
装饰对象和真实对象有相同的接口。这样客户端对象就可以和真实对象相同的方式和装饰对象交互。

(2) 装饰对象包含一个真实对象的引用(reference)

(3) 装饰对象接受所有来自客户端的请求。它把这些请求转发给真实的对象。

(4)
装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中,通常是通过继承来实现对给定类的功能扩展。

 

结构图:

 

举例:假设我们要开发一个照相管用的程序





1

2

3

4

5

6

7

8

9

10

11

12

13

14

    //照相

  public  abstract class Picture

    {

        public abstract void Draw();

    }

    //绘制一个照片

   public class People : Picture

   {

       public override void Draw()

       {

           Console.WriteLine("照一张相片");

       }

   }

假设我们不仅只照相,而且为了满足客户的需要有的时候需要给相片增加一个相框





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

 public interface PhotoFrame

   {

        void SetFrame();

   }

   public class PeopleWithFram :People, PhotoFrame

   {

       public override void Draw()

       {

           base.Draw();

           //照完加相框

           SetFrame();

       }

       public void SetFrame()

       {

           //给相片加相框方法

       }

   }

好 需求又来了,毕竟有钱人还是很多了嘛,不仅要相框,还需要打蜡上保护膜





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

public interface ProtectPic

   {

        void ProtectImage();

   }

   public class PeopleWithFramWithProtect : People, PhotoFrame, ProtectPic

   {

       public override void Draw()

       {

           base.Draw();

           //先上保护膜打上蜡

           ProtectImage();

           //在上相框

           SetFrame();

       }

       public void SetFrame()

       {

           //给相片加相框方法

       }

       public void ProtectImage()

       {

           //给相片打蜡上保护膜

       }

   }

/好,这个时候需求又来了,毕竟不是人人都那么完美,毕竟有丑姑娘嘛,需要PS处理一下,那我们是不是又得定义一个PS接口,然后写个子类去继承呢?“子类复子类,子类何其多”。这种接口继承的方式虽然是解决问题,同时也带来了一系列新的问题,子类可能需要多重继承,这个在某些情况下违反了类的单一职责。后续如来来新的需求子类会变的非常庞大。

我们看看装饰是怎么解决这个问题的





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

 public class Decorate : Picture

   {

       public  Picture picture;

       public  Decorate(Picture pic)

       {

         this.picture=pic;

       }

       public override void Draw()

       {

           Console.WriteLine("照一张相片");

       }

   }

    //相框

   public class WithFram : Decorate

   {

      

       public  WithFram(Picture pic):base(pic)

       

       }

       public override void Draw()

       {

           SetFrame();

           base.Draw();

       }

       public void SetFrame()

       {

           //给相片加相框方法

       }

   }

    //打蜡上保护膜

   public class WithProtect : Decorate

   {

       public WithProtect(Picture pic)

           base(pic)

       

       }

       public override void Draw()

       {

           ProtectImage();

           base.Draw();

       }

       public void ProtectImage()

       {

           //给相片打蜡上保护膜

       }

   }

   

   class Program

    {

        static void Main(string[] args)

        {

            //照相

            Picture pic = new People();

            pic.Draw();

            //照完像上蜡上保护膜

            Picture picProtect = new People();

            Decorate dec = new WithProtect(pic);

            dec.Draw();

            //照完上蜡上保护膜上相框  

            Picture picProtectFrame = new People();

            Decorate decProtect = new WithProtect(picProtectFrame);

            Decorate frame = new WithFram(decProtect);//Decorator模式的精妙所在

            frame.Draw();

        }

    }

用装饰模式,大大减少了子类的继承,并且在调用的时候,可以对上级对象进行再次封装,这个也是Decorator模式非常经典的一个地方!

 

适用性:

 

以下情况使用Decorator模式

1. 需要扩展一个类的功能,或给一个类添加附加职责。

2. 需要动态的给一个对象添加功能,这些功能可以再动态的撤销。

3.
需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。

4.
当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

 

优点:

1.
Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。

2.
通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

缺点:

1. 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。

2. 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。

3.
装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。


设计原则:

1. 多用组合,少用继承。

利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。然而,如果能够利用组合的做法扩展对象的行为,就可以在运行时动态地进行扩展。

2. 类应设计的对扩展开放,对修改关闭

设计模式系列文章入口

时间: 2024-11-05 06:15:43

第8章 装饰模式(Decorator Pattern)的相关文章

装饰模式(Decorator pattern)

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

设计模式-装饰模式(Decorator Pattern)

Attach additional responsibilities to an object dynamically keeping the same interface.Decorators provide a flexible alternative to subclassing for extending functionality.(动态地给一个对象添加一些额外的职责.就增加功能来说,装饰模式相比生成子类更为灵活.) 装饰模式有四个角色:1.Component抽象构件Component

[设计模式]<4>. C++与装饰模式(decorator pattern)

原文地址: http://www.cnblogs.com/hebaichuanyeah/p/5612028.html 装饰模式是指,动态的为一个类增加职责(相对于继承). 截自<设计模式>装饰者的UML图 举个栗子,

设计模式实现C++ --装饰模式Decorator Pattern

定义:动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案. 类图: Component:定义一个对接接口,可以给这些对象动态的添加职责: ConcreteComponent:定义一个具体的对象,也可以给对象添加一些职责: Decorator:装饰抽象类,继承了Component,从外类来扩展Component类的功能,对于Component来说无需知道Decorator的存在: ConcreteDecorator:具体的装饰对象,起到给Component添加职责的功能:

DesignPattern_Java:Decorator Pattern

装饰模式 Decorator Pattern Attach additional responsibilities to an object dynamically keeping the same interface.Decorators provide a flexible alternative to subclassing for extending functionality. 动态地给一个对象添加一些额外的职责.就增加功能来说,装饰模式比生成子类更为灵活. 抽象构建角色(Compon

装饰模式Decorator

第三章 装饰模式Decorator  1.1 什么是装饰模式? 装饰模式Decorator,动态的给一些对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活 1.2装饰模式Decorator的结构图 Component是定义一个对象接口,可以给这些对象动态的添加职责. ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责. Decorator装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,

第 13 章 装饰模式【Decorator Pattern】

以下内容出自:<<24种设计模式介绍与6大设计原则>> Ladies and gentlemen,May I get your attention,Please?,Now I’m going to talk about decoratorpattern.装饰模式在中国使用的那实在是多,中国的文化是中庸文化,说话或做事情都不能太直接,需要有技巧的,比如说话吧,你要批评一个人,你不能一上来就说你这个做的不对,那个做的不对,你要先肯定他的成绩,表扬一下优点,然后再指出瑕疵,指出错误的地方

NET设计模式 第二部分 结构性模式(9):装饰模式(Decorator Pattern)

装饰模式(Decorator Pattern) ——.NET设计模式系列之十 Terrylee,2006年3月 概述 在软件系统中,有时候我们会使用继承来扩展对象的功能,但是由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性:并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀.如何使“对象功能的扩展”能够根据需要来动态地实现?同时避免“扩展功能的增多”带来的子类膨胀问题?从而使得任何“功能扩展变化”所导致的影响将为最低?这就是本文要讲的Decorat

设计模式之第4章-装饰模式(Java实现)

设计模式之第4章-装饰模式(Java实现) “怎么了,鱼哥?” “唉,别提了,网购了一件衣服,结果发现和商家描述的差太多了,有色差就算了,质量还不好,质量不好就算了,竟然大小也不行,说好的3个X,邮的却是一个X的,不说了,退货去.你先开讲吧,你说说就一个东西还装饰个什么劲儿.”(装饰模式石化中:这关我什么事儿撒.)恩,今天由我来讲,讲之前先来个段子:话说面条被追到一个理发店,出来一个方便面,然后追他的人一把抓住他就开打:小子(第四声),烫个头发我就不认识你了么?其实那人认错了,出来的真的是方便面