Decorator 装饰模式

问题的提出:

李建中 老师给出的引子:

子类复子类,子类何其多
假如我们需要为游戏中开发一种坦克,除了各种不同型号的坦克外,我们还希望在不同场合中为其增加以下一种或多种功能:比如红外线夜视功能,比如水陆两栖功能,比如卫星定位功能等等。

//  抽象坦克
public   abstract   class  Tank  {
public abstract Shot();
public abstract 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  {…}
public   class  T50BC: T50, IB, IC  {…}
public   class  T50ABC: T50, IA, IB, IC {}
………………

可见,当我们增加一种功能时,涉及到计到的子类会很多。

  问题的根源:
当我们过度地使用了继承来扩展对象的功能,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀(多继承)。
解释:  静态特质:在编译的时候需确定的东西,动态性是指在运行时来改变、扩展,如虚函数。

解决思路

使“对象功能的扩展能够根据需要来动态地(在运行时)实现,同时避免扩展功能的增多带来的子类膨胀问题,从而使得任何功能扩展变化所导致的影响将为最低。
代码表示:

   public   abstract   class  Tank
      
{
         
public abstract void Shot();
         
public abstract void Run();
     }

 
     
// 接口继承和Has-A组合使用技巧
      public   abstract   class  Decorator : Tank  // Is-A 是接口继承
       {
         
private Tank tank; //Has-A 对象组合 被装饰的对象
 
         
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 some extension  //功能扩展(如红外功能扩展)
 
             
//do shot 
             base.Shot();
             
         }

         
public override void Run()
          
{
             
//Do some extension  //功能扩展(如红外功能扩展)
 
             
//do run 
             base.Run();
         }

     }

 
     
public   class  DecoratorB : Decorator
      
{
         
public DecoratorB(Tank tank) : base(tank)
          
{
         
         }

 
         
public override void Shot()
          
{
             
//Do some extension  //功能扩展(如水陆两栖功能扩展)
 
             
//do shot 
             base.Shot();
             
         }

         
public override void Run()
          
{
             
//Do some extension  //功能扩展(如水陆两栖功能扩展)
 
             
//do run 
             base.Run();
         }

     }

 
 
     
public   class  T50 : Tank
      
{
         
public override void Shot()
          
{
         
         }

         
public override void Run()
          
{
 
         }

     }

 
     
public   class  T75 : Tank
      
{
         
public override void Shot()
          
{
         
         }

         
public override void Run()
          
{
 
         }

     }


主程序:
         
public   static   void  Main()
          
{
             Tank tank 
= new T50();                //T50型号
             DecoratorA da = new DecoratorA(tank); //红外功能
             DecoratorA db = new DecoratorA(da);  //两栖功能 
 
             db.Shot();     
//db是同时具有红外,两栖功能的T50型号的Tank对象
             db.Run();
         }


看完这段代码我很兴奋,把前边那种令人崩溃的情况巧妙的解决了,新增加一种功能时变得容易多了,程序的结构也清晰自然了。

  Decorator 模式并非解决 多子类衍生的多继承 问题, Decorator 模式 应用的要点在于解决 主体类在多个方向上的扩展功能
   感想:设计模式是对现实的抽象,只有准确的把握对象的本质,使对象的划分符合现实,这样设计出来的程序才能结构清晰,更容易的面对变化,感觉设计模式似乎是哲学问题在软件开发领域的一种表述。呵呵,不知道朋友们有没有同感。

你可能感兴趣的:(Decorator)