此模式采用组合非继承的方式来扩展对象职责.
.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); } }
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);
也可以继续定义装饰器,如添加文字功能
photo = new Photo(); tag = new TaggedPhoto (photo,"Jug"); composition = new BorderedPhoto(tag, Color.Yellow);
此模式原型有个缺点,即每个装饰器,必须要调用其中组件的方法.虽然灵活,当改进后的行为模式更加方便.可以添加一个集合来存取一个装饰器的集合.
模式可灵活运用之,不必死套,在编码中自然就可以体现的出来.