导航

也谈装饰模式

Posted on 2011-10-13 16:14  雨夜孤鹤  阅读(148)  评论(0编辑  收藏  举报

一言概括:通过组合的方式实现对象功能的动态添加或删除。

图例:下面这个图片是装饰模式官方的说明,大家先看一下有个印象即可。

File:UML2 Decorator Pattern.png

这个图相对抽象,我们来通过一个列子来说明:

有一个渔民救了一条金鱼,金鱼对渔民说:我帮你实现个愿望吧。渔民很高兴,说:好啊,我要一个房子。金鱼问:没问题,什么样子的房子呢。渔民说:很简单的就好了。毕竟我们的金鱼生活在水里,不懂得人类的生活,所以就创造了一个没有窗户没有门的房子。渔民回去一看,心想:哎呀,这也没办法住啊。于是告诉金鱼:这个房子我没法住,再给我加个门吧。金鱼说:这个房子造好了就没法改了,我在给你照原样复制一个,不过会多一个门。于是,现在有2个房子,一个没门,一个有门。可有一天问题又出现了:金鱼啊,再把这两个房子给我加上窗户啊。于是可怜的金鱼不得不分别复制那两个房子,然后分别加上窗户。。。。。,请大家注意,我们的渔民要的是几个房子:有门有窗,没门有窗。。,而且不一定什么时候喜欢住什么样子的。。。

相信大家看明白了,以上这个例子就是通过继承来实现功能的增加。问题在哪里呢?问题在于需要功能任意组合的时候就会出现上文的问题。

现在继续这个故事,随着渔民的要求不断增加,金鱼终于受不了了,这样既麻烦又浪费砖头等资源。于是施展魔法,时光倒流。发明了一个机器,里面有很多房子组建,有门,窗户,到处是洞的砖头架子。。。。,这下好了,可以根据渔民不同的需求自动组装成不同的样子了~

我们故事的续集就是用组合的方式实现功能增加。用继承的方式只能在编译的时候确定需要的功能,而用我们的装饰模式可以在运行的时候动态的实行功能的组合。

现在结合上面的图片,这次不讲继承,只讲模式。

一个类用来输出窗口叫 SimpleWindow ,只负责输出最简单的窗体。如果要输出带有滚动条的时候该怎么办呢?举例来说,

class DrawWindow
{

  public void DrawWindow()
  {

    Console.WriteLine("SimpleWindow");
  }
}

接下来声明一个专门用来给窗口装饰滚动条的“机器”:

class ScrollWindow
{

     private DrawWindow mDrwWin;

    public ScrollWindow(DrawWindow drwWin)
  {

    mDrwWin = drwWin;   
   }

     public void DrawWindow()
  {

    Console.WriteLine("Count scroll");

           mDrwWin.DrawWindow();
  }
}

大家知道,装饰器只应该起到装饰的作用 ,而物体的本质是不能变的。就是说,安了窗户的房子还是房子,所以装饰器要和被装饰的东西继承一个接口 。

总结 : 学习装饰器模式主要掌握2点即可,

1,装饰器的本质。

2,与继承的区别。