/*
* 使用场景:游戏中需要开发坦克,坦克具有不同型号【如T50,T70,T90等】,而且希望不同型号的坦克具有一种或者多种功能[红外,水陆两用,卫星定位等]。
* 通常的解决方案:
* public abstract class Tank(){}
* T50:Tank T70:Tank T90:Tank
* IA IB IC //红外,水陆,卫星定位的功能接口
* T50A:T50,IA T50B:T50,IB T50C:T50,IC
* T50AB:T50,IA,IB .....
* 由此,存在的问题,当需要为一种类型[T50系列]增加一个功能[如对空导弹],就需要修改和T50相关的所有类。
* 也就是说,这种解决方案存在一个问题,那就是类数目的指数级别增长,当需求改变是,需要更改的代价很大。
*
* 问题深入分析:
* 过度使用了继承来扩展对象的功能。由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活【编译的时候生成,而不是运行的时候生成】。
* 并且,随着子类的增多,各种子类的组合导致子类的膨胀。
* 目标:“对象功能的扩展”能够根据需求来动态地【运行的时候实现】实现,同事避免“扩展功能的增多”带来子类的膨胀问题。
*
* 意图:动态地给一个对象增加一些额外的职责。
*
* UML图说明:
* Component-----Tank,
* ConcreteConponent-----T50,T70...
* Decorator----Decorator
* ConcreteDecoratorA----DecoretorA, ConcreteDecoratorB----DecoretorB
*
*/
namespace sington1
{
public abstract class Tank
{
public abstract void Shot();
public abstract void Run();
}
public class T50 : Tank
{
public T50()
{ System.Console.WriteLine("T50"); }
public override void Shot()
{
}
public override void Run()
{
}
}
public class T70 : Tank
{
public T70()
{ System.Console.WriteLine("T70"); }
public override void Shot()
{
}
public override void Run()
{
}
}
/*Decorator继承了Tank,这里实际上是继承了他的接口,而不是具体类的继承。
*
*/
public abstract class Decorator : Tank
{
private Tank _tank;//对象组合
public Decorator(Tank tank)
{
this._tank = tank;
}
public override void Shot()
{
_tank.Shot();
}
public override void Run()
{
_tank.Run();
}
}
public class DecoratorA:Decorator
{
public DecoratorA(Tank tank):base(tank)
{
}
public override void Shot()
{
//红外功能扩展
//do shot
base.Shot();
System.Console.WriteLine("红外功能扩展");
}
public override void Run()
{
//红外位功能扩展
//do Run
base.Run();
}
}
public class DecoratorB : Decorator
{
public DecoratorB(Tank tank)
: base(tank)
{
}
public override void Shot()
{
//卫星定位功能扩展
//do shot
base.Shot();
System.Console.WriteLine("卫星定位功能扩展");
}
public override void Run()
{
//卫星定位功能扩展
//do Run
base.Run();
}
}
/*通过采用组合,而非继承的手法,Decorator模式实现了运行时动态地扩展对象功能的能力,而且可以根据需求扩展多个功能,
* 避免了单独似乎用继承带来的“灵活性差”和“多子类衍生问题”。
*
*/
class decorator
{
public static void Main()
{
Tank tank = new T50(); //得到T50坦克
DecoratorA da = new DecoratorA(tank); //装饰为具有红外功能的T50
DecoratorB dab = new DecoratorB(da); //装饰da为具有卫星定位功能,还可以对该坦克进行扩展。
dab.Shot();
/*输出结果:
* T50
* 红外功能扩展
* 卫星定位功能扩展
*/
System.Console.WriteLine("End");
}
}