using System;
using System.Text;
using System.Collections.Generic;
using System.Data.Linq;
using System.Data.Linq.SqlClient;
namespace Test
{
class Clock //基类 所有派生于此类的类 必须要有Get方法
{
public virtual string Get()
{
return "The time is";
}
}
class ClockDecorator : Clock //装饰类 用以装饰基类及其派生类
{
private Clock _clock;
public ClockDecorator(Clock clock)
{
this._clock=clock;
}
public override string Get ()
{
return this._clock.Get();
}
}
class AddString : ClockDecorator //装饰器子类 用以给基类或其派生类添加新职责
{
public AddString(Clock clock):base(clock)
{
}
public override string Get ()
{
string s=base.Get ();
return s+" "+DateTime.Now.ToString();
}
}
class Program
{
public static void Main()
{
Clock c=new Clock();
ClockDecorator cd=new AddString(c);
Console.WriteLine(cd.Get());
}
}
}
上面写的code,简单的用来实现了对clock类对象的“装饰”。
所谓装饰,就是在不改变原有类的基础上,在外部给此类添加一些职责功能。可以创建很多装饰器子类,用来给基类装饰。而不用继承子类的方式,这样做的好处是可以避免过多的子类,以上的代码可能对“有效避免子类”难免会有岐义,那么来扩充下:
using System;
using System.Text;
namespace Test
{
abstract class ClockBase
{
public abstract string Get();
}
class Clock : ClockBase
{
public override string Get()
{
return "The time is";
}
}
class ClockDecorator : ClockBase
{
private Clock _clock;
public ClockDecorator(Clock clock)
{
this._clock=clock;
}
public override string Get ()
{
return this._clock.Get();
}
}
class AddString : ClockDecorator
{
public AddString(Clock clock):base(clock)
{
}
public override string Get ()
{
string s=base.Get ();
return s+" "+DateTime.Now.ToString();
}
}
class Program
{
public static void Main()
{
Clock c=new Clock();
ClockDecorator cd=new AddString(c);
Console.WriteLine(cd.Get());
}
}
}
这里Clock和ClockDecorator有一个共通的基类ClockBase,并共有一个必须要实现的抽象方法,在主程序中,实例化一个要添加对象职责的类Clock,并定义一个装饰器对象,并用装饰器子类来实例化此对象,装饰器子类有个构造函数,并把Clock实例对象添加到构造函数中去,那么此时可以说cd对象,在一定程度上,就是c对象经过了装饰后的对象,当然了,如果用对象标识来确定对象的划分的话,cd对象不是c对象,虽然他们拥有一个共通的基类和方法。
此时运行以上代码,可以看到会输出原本在Clock中并没有包含的东西,也就是具体的时间是在装饰过后才有的。
当然想要扩充对象的功能,可以用继承,但是请设想以下,一个基类有很多个子类,如果要给每个子类添加一个或几个很少用到的功能,那么就又要生成很多个子类的子类。如果采用装饰器模式,那么尽管它有很多子类,那么我只要包装其生成的对象,就可以给此对象,添加不止一个功能,但是写的子类确实大大的减少了要生成的子类的子类。
以上说的都是装饰器的优点,可以减少子类的产生,而且用来扩充功能的装饰器子类,可以很专一的负责一个职责,而要添加几个职责,那么就可以采用生成相应的,功能单一的装饰器子类来装饰要装饰的对象。而且可以在执行原有对象的前后,添加一些其他的功能,比如说日志记录,系统状态输出,输出提示值等相应的功能。因为装饰器子类都是从装饰器类派生出来的,那么就可以对相应的方法进行嵌套,来达到按照一定的流程来进行一定的流程化操作。
装饰器模式的缺点。事物都有两面性,所以有好就有不好的地方。它的主要缺点,一是此对象非彼对象,也就是上面例子中的cd和c,追根纠底不是完全一样的对象标识!二是,在实例化装饰器子类实会产生相应的对象,这样会导致要添加的职责越多,越要生成越多的装饰器子类对象,比较难以控制。
所以任何模式,过犹不及是真理,要适度,比如在较少使用某个功能,而类本身却缺少的此功能的情况下,但是这些功能不依赖于类本身,如果要派生子类的话,会有杂乱而且不合适,造成维护困难,并违反单一职责原则,那么就我目前的水平来说,我会考虑用此模式来适当的扩充对象职责。
有任何错误或失实之处,恳请评论批评。