代码改变世界

装饰模式

2010-08-26 22:06  Clingingboy  阅读(575)  评论(0编辑  收藏  举报

      此模式采用组合非继承的方式来扩展对象职责.

image_2

.net的应用中,如asp.net ajax的behavior,wpf和silverlight的附加属性,都可以认为是装饰模式的变体.但稍微有些变化.都起到了装饰的作用.

上面的uml图给予一个参考,但非死规定,理解思想就好,如接口也可以是抽象类.

来看一个关于图片的示例

1.定义组件基类(Component,缺省无接口),呈现一幅图片

public class Photo : Form
      {
      Image image;
      public Photo () {
        image = new Bitmap("jug.jpg");
        this.Text = "Lemonade";
        this.Paint += new PaintEventHandler(Drawer);
      }
 
      public virtual void Drawer(Object source, PaintEventArgs e) {
        e.Graphics.DrawImage(image,30,20);
      }
 
      private void InitializeComponent()
      {
          this.SuspendLayout();
          // 
          // Photo
          // 
          this.ClientSize = new System.Drawing.Size(283, 250);
          this.Name = "Photo";
          this.ResumeLayout(false);
      }
    }

image_4

2.添加图片边框装饰对象

其在构造函数中传入了一个Photo对象,在原基础上画了一个边框

class BorderedPhoto : Photo {
   Photo photo;
   Color color;
 
   public BorderedPhoto (Photo p, Color c) {
     photo = p;
     color=c;
   }
 
   public override void Drawer(Object source, PaintEventArgs e) {
     photo.Drawer(source, e);
     e.Graphics.DrawRectangle(new Pen(color, 10),25,15,215,225);
   }
 }

调用方法如下

BorderedPhoto composition = new BorderedPhoto(new Photo(), Color.Blue);


效果如下
image_8 

也可以继续定义装饰器,如添加文字功能

photo = new Photo();
 tag = new TaggedPhoto (photo,"Jug");
 composition = new BorderedPhoto(tag, Color.Yellow);

image_10

 

此模式原型有个缺点,即每个装饰器,必须要调用其中组件的方法.虽然灵活,当改进后的行为模式更加方便.可以添加一个集合来存取一个装饰器的集合.

模式可灵活运用之,不必死套,在编码中自然就可以体现的出来.