zoukankan      html  css  js  c++  java
  • GOF之装饰模式

    问题的引入:

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

    通过子类继承发现代码冗余太严重

    动机(Motivation)

    上述描述的问题根源在于我们“过度的使用了继承来扩展对象的功能”,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀(多继承)。

    如何使“对象功能的扩展”能够根据需要来动态地实现?同时避免“扩展功能的增多”带来的子类膨胀问题?从而使得任何“功能扩展变化”所导致的影响将为最低?

    意图(Intent)

    动态地给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类更为灵活。

    结构(Structure)

    代码实现:

     1 装饰的抽象类和实体类
     2 public abstract class Decorator:Tank
     3     {
     4         protected Tank tank;
     5         public Decorator(Tank tank)
     6         {
     7             this.tank = tank;
     8         }
     9 
    10 
    11         public override void Run()
    12         {
    13             tank.Run();
    14         }
    15 
    16         public override void Shot()
    17         {
    18             tank.Shot();
    19         }
    20     }
    21 
    22     public class DecoratorA : Decorator
    23     {
    24         public DecoratorA(Tank tank)
    25             : base(tank)
    26         { }
    27         public override void Run()
    28         {
    29             Console.Write("带红外功能的");
    30             base.Run();
    31         }
    32         public override void Shot()
    33         {
    34             Console.Write("带红外功能的");
    35             base.Shot();
    36         }
    37     }
    38     public class DecoratorB : Decorator
    39     {
    40         public DecoratorB(Tank tank)
    41             : base(tank)
    42         { }
    43         public override void Run()
    44         {
    45             Console.Write("带水陆双栖功能的");
    46             base.Run();
    47         }
    48         public override void Shot()
    49         {
    50             Console.Write("带水陆双栖功能的");
    51             base.Shot();
    52         }
    53     }
    54     public class DecoratorC : Decorator
    55     {
    56         public DecoratorC(Tank tank)
    57             : base(tank)
    58         { }
    59         public override void Run()
    60         {
    61             Console.Write("带卫星定位功能的");
    62             base.Run();
    63         }
    64         public override void Shot()
    65         {
    66             Console.Write("带卫星定位功能的");
    67             base.Shot();
    68         }
    69     }
     1 需要被装饰的对象的抽象类和实体类
     2  public abstract class Tank
     3     {
     4         public abstract void Run();
     5         public abstract void Shot();
     6     }
     7     public class T50 : Tank
     8     {
     9 
    10         public override void Run()
    11         {
    12             Console.Write("T50运行");
    13         }
    14 
    15         public override void Shot()
    16         {
    17             Console.Write("T50攻击");
    18         }
    19     }
    20     public class T75 : Tank
    21     {
    22 
    23         public override void Run()
    24         {
    25             Console.Write("T75运行");
    26         }
    27 
    28         public override void Shot()
    29         {
    30             Console.Write("T75攻击");
    31         }
    32     }
    33 
    34     public class T90 : Tank
    35     {
    36 
    37         public override void Run()
    38         {
    39             Console.Write("T90运行");
    40         }
    41 
    42         public override void Shot()
    43         {
    44             Console.Write("T90攻击");
    45         }
    46     }
     1 主函数的调用
     2  static void Main(string[] args)
     3         {
     4             Tank tank = new T75();
     5             DecoratorA da = new DecoratorA(tank);
     6             DecoratorB db = new DecoratorB(da);
     7             DecoratorC dc = new DecoratorC(db);
     8             dc.Run();
     9             Console.WriteLine();
    10             dc.Shot();
    11             Console.ReadKey();
    12         }

    Decorator模式的几个要点:

    通过采用组合、而非继承的手法,Decorator模式实现了在运行时动态地扩展对象功能的能力,而且可以根据需求扩展多个功能。避免了单独使用继承带来的“灵活性差”和“多子类衍生问题”。

    Component类在Decorator模式中充当抽象接口的角色,不应该去实现具体的行为。而且Decorator类对于Component类应该透明--换言之Component类无需知道Decorator类,Decorator类是从外部来扩展Component类的功能。

    Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类所具有的接口。但在实现上又表现为has-a Component的组合关系,即Decorator类又使用了另外一个Component类。我们可以使用一个或者对个Decorator对象来“装饰”一个Component对象,且装饰后的对象仍然是一个Component对象。

    Decorator模式并非解决“多子类衍生的多继承”问题,Decorator模式应用的要点在于解决“主体类在多个方向上的扩展功能”--是为“装饰的含义”。

    .NET框架中的Decorator应用:

  • 相关阅读:
    团队选题报告
    结对编程作业服务器端总结
    结对编程作业服务器端系统设计、玩法和接口简要
    第一次团队展示
    第一次个人编程作业技术助教总结
    第一次个人编程作业输入输出格式及注意事项
    第一次博客作业
    课程总结
    团队作业-个人总结
    团队作业总结
  • 原文地址:https://www.cnblogs.com/pushudepu/p/6039666.html
Copyright © 2011-2022 走看看