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

 


 

代码

    
//抽象坦克
    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)


 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模式应用的要点在于解决"主题类在多个方向上的扩展功能"---是为"装饰"的含义

 

posted @ 2010-01-05 00:53  疯狂的咸鱼  阅读(301)  评论(0编辑  收藏  举报