装饰器模式提供了一种在无需创建新的派生类的情况下修改个体对象行为的方式。
假设我们需要给工具栏中的按钮添加一个特殊的边框,如果我们创建一个新的派生出来的按钮类,那么就意味着这一新类的所有按钮都会有相同的特殊的边框,这可能并不是我们最初想要的结果。替代的做法是,我们可以创建一个装饰器类来修饰按钮,然后从这一主修饰器类中派生出任意特定的装饰器,每个装饰器完成某种特定类型的装饰。这是另一种对象包含比对象继承更受青睐的情况,装饰器是一个图像对象,但是包含了其所装饰的对象,他可以拦截一些图形方法的调用,执行一些附加的计算,然后再把调用传递给其所装饰的底层对象。
C#的空间中没有类似的按钮行为,不过我们可以通过装饰一个面板,并使用面板来包含按钮的方式来获得这样的行为。
设计模式一书中建议装饰器应该派生于某个一般性的可视化空间类,然后实际按钮的每个消息都由装饰器类来转发。装饰器这样的类应该作为抽象类,并且应该从该抽象类中派生出所有的做实际工作的装饰器。
这样我们这个装饰器的抽象就可以定义为:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace CoolDec
{
/// <summary>
/// Summary description for Decorator.
/// </summary>
public interface Decorator
{
void mouseMove(object sender, MouseEventArgs e);
void mouseEnter(object sender, EventArgs e);
void mouseLeave(object sender, EventArgs e);
void paint(object sender, PaintEventArgs e);
}
}
要实现的对按钮的装饰效果如图:当鼠标放上按钮以后显示一个特殊的边框
具体的装饰器类的定义:
using System;
using System.Windows.Forms;
using System.Drawing ;
namespace CoolDec
{
/// <summary>
/// Summary description for CoolDecorator.
/// </summary>
public class CoolDecorator :Panel, Decorator
{
protected Control contl;
protected Pen bPen, wPen, gPen;
private bool mouse_over;
protected float x1, y1, x2, y2;
//----------------------------------
public CoolDecorator(Control c) {
contl = c; //copy in control
//add button to controls contained in panel
this.Controls.AddRange(new Control[] {contl});
locate(c.Location );