Decorator装饰模式是一种结构型模式,它主要是解决:“过度地使用了继承来扩展对象的功能”,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀(多继承)。继承为类型引入的静态特质的意思是说以继承的方式使某一类型要获得功能是在编译时。所谓静态,是指在编译时;动态,是指在运行时。
GoF《设计模式》中说道:动态的给一个对象添加一些额外的职责。就增加功能而言,Decorator模式比生成子类更为灵活。
代码1:被装饰的对象
public abstract class AbstractCellPhone { public abstract string CallNumber(); public abstract string SendMessage(); } public class NokiaPhone : AbstractCellPhone { public override string CallNumber() { return "NokiaPhone call sombody"; } public override string SendMessage() { return "NokiaPhone send a message to somebody"; } } public class MotoPhone : AbstractCellPhone { public override string CallNumber() { return "MotoPhone call sombody"; } public override string SendMessage() { return "MotoPhone send a message to somebody"; } }
代码2:装饰者
public abstract class Decorator : AbstractCellPhone { AbstractCellPhone _phone; public Decorator(AbstractCellPhone phone) { _phone = phone; } public override string CallNumber() { return _phone.CallNumber(); } public override string SendMessage() { return _phone.SendMessage(); } } public class DecoratorGPS : Decorator { public DecoratorGPS(AbstractCellPhone phone) : base(phone) { } public override string CallNumber() { return base.CallNumber() + " with GPS"; } public override string SendMessage() { return base.SendMessage() + " with GPS"; } } public class DecoratorBlueTooth : Decorator { public DecoratorBlueTooth(AbstractCellPhone phone) : base(phone) { } public override string CallNumber() { return base.CallNumber() + " with BlueTooth"; } public override string SendMessage() { return base.SendMessage() + " with BlueTooth"; } }
代码3:客户端调用
public class Client { static void Main1(string[] args) { AbstractCellPhone phone = new NokiaPhone(); Console.WriteLine(phone.CallNumber()); Console.WriteLine(phone.SendMessage()); //add GSP DecoratorGPS gps = new DecoratorGPS(phone); Console.WriteLine(gps.CallNumber()); Console.WriteLine(gps.SendMessage()); //add bluetooth DecoratorBlueTooth bluetooth = new DecoratorBlueTooth(gps); Console.WriteLine(bluetooth.CallNumber()); Console.WriteLine(bluetooth.SendMessage()); Console.Read(); } }