Decorator装饰(结构型模式)
子类复子类,子类何其多
假如我们需要为游戏开发一种坦克,除了各种不同型号的坦克外,我们还希望在不同场合下为其为其增加一种或多种功能:比如红外线夜视功能,比如水陆两栖功能,比如卫星定位功能等等。
//抽象坦克
public abstract class Tank
{
public abstract void Shot();
public abstract void Run();
}
//各种型号
public class T50:Tank{}
public class T75:Tank{}
public class T90:Tank{}
//各种不同功能的组合
public class T50A : T50, IA { }
public class T50B : T50, IB { }
public class T50C : T50, IC { }
public class T50AB : T50, IA, IB { }
//T50BC,T50AC,T50ABC
如果再增加一种功能ID,就得增加,T50AD,T50BD...无语了...还有T75**,T90**
动机(Motivation)
上述描述的问题根源在于我们"过度地使用了继承来扩展对象的功能",由于继承为类型引入的静态特质(继承必须在编译前实现),使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀(多继承)
如何使"对象功能的扩展"能够根据需要来动态地(运行时)实现?同事避免"扩展功能的增多"带来的子类膨胀的问题?从而使得任何"功能扩展化"所导致的影响降为最低?
意图(Intent)
动态地给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类更为灵活
---《设计模式》GoF
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//抽象坦克
public abstract class Tank
{
public abstract void Shot();
public abstract void Run();
}
public abstract class Decorator : Tank //接口继承
{
private Tank _tank; //Hsa - A 对象组合-----关键点
public Decorator(Tank tank)
{
this._tank = tank;
}
public override void Shot()
{
_tank.Shot();
}
public override void Run()
{
_tank.Run();
}
}
//功能1--装饰A
public class DecoratorA : Decorator
{
public override void Shot()
{
//在这里扩展DecoratorA的扩展
base.Shot();
}
public override void Run()
{
//在这里扩展DecoratorA的扩展
base.Run();
}
}
//功能2--装饰B
public class DecoratorB : Decorator
{
public override void Shot()
{
//在这里扩展DecoratorB的扩展
base.Shot();
}
public override void Run()
{
//在这里扩展DecoratorB的扩展
base.Run();
}
}
class App
{
public static void Main()
{
Tank tank = new T50();
DecoratorA da = new DecoratorA(tank); //增加功能1
DecoratorA db = new DecoratorB(da); //增加功能2
}
}
结构(Structure)
![](https://images.cnblogs.com/cnblogs_com/jonniexie/%E8%B4%B4%E5%9B%BE%E7%9B%B8%E5%86%8C/10.1.jpg)
Decorator模式的几个要点
·通过采用组合而非继承的手法,Decorator模式实现了在运行时动态扩展对象功能的能力,而且可以根据需要扩展多个功能。避免了单独使用继承带来的"灵活性差"和"多子类衍生问题"。
·Componet类在Decorator模式中充当抽象接口的角色,不应该去实现具体的行为。而且Decorator类对于ponnet类应该透明---换言之Component类无需知道Decorator类,Decorator类是从外部来扩展Component类的功能。
·Decorator类在接口上表现为is-a Componnet的继承关系,即Decorator类继承了Component类所具有的接口。但在实现上又表现为has-a Component的组合关系,即Decorator类又使用了另外一个Component类。我们可以使用一个或者多个Decoratort对象来"装饰"一个Component对象,切装饰后的对象仍然是一个Component对象。
·Decorator模式并非解决"多子类衍生的多继承"问题,Decorator模式应用的要点在于解决"主题类在多个方向上的扩展功能"---是为"装饰"的含义