读书笔记3:装饰模式

来源:互联网 发布:阿里云个人备案照片 编辑:程序博客网 时间:2024/06/08 10:14
1、背景
   给对象增加新功能,如何实现:
   (1)、在原类里面增加——违背开放封闭原则,类可以扩展但不能被修改。
   (2)、利用继承扩展功能——造成类不断增多。
    例子:给汽车增加对讲机系统,GPS定位系统,影视播放等,这些都不是汽车类的属性。如何增加?
 2、认识装饰模式
 装饰模式模型如下:
 
[csharp] view plaincopyprint?
  1. 1、Component类  
  2.  public abstract class Component  
  3.   {  
  4.         public abstract void Opration();  
  5.   }  
  6.  2、ConcreteComponent类  
  7.  public class ConcreteComponent:Component  
  8.   {  
  9.      public override void Opration()  
  10.      {  
  11.        //具体对象的操作  
  12.      }  
  13.   }  
  14.  3、Decorator类  
  15.   public abstract class Decorator:ConcreteComponent  
  16.   {  
  17.      protected Component component;  
  18.      public void SetComponent(Component dComponent)  
  19.      {  
  20.        component = dComponent;  
  21.      }  
  22.       public override void Opration()  
  23.       {  
  24.         base.Opration();  
  25.       }  
  26.   }  
  27.  4、具体的装饰类  
  28.  public class ConcreteDecoratorA : Decorator  
  29.  {  
  30.      private string addState;//本类独有的,区别与ConcreteDecoratorB  
  31.      public override void Opration()  
  32.      {  
  33.         base.Opration();  
  34.         addState = "新状态";  
  35.         //具体装饰对象A的操作  
  36.      }  
  37.  }  
  38.  public class ConcreteDecoratorB : Decorator  
  39.  {  
  40.     public override void Opration()  
  41.      {  
  42.         base.Opration();  
  43.          //AddBehavior();  
  44.          //具体装饰对象A的操作  
  45.      }  
  46.  }  
  47.  客户端调用:  
  48.   static void Main(string[] args)  
  49.    {  
  50.       ConcreteComponent c = new ConcreteComponent();  
  51.       ConcreteDecoratorA a = new ConcreteDecoratorA();  
  52.       ConcreteDecoratorB b = new ConcreteDecoratorB();  
  53.         
  54.       a.SetComponent(c);  
  55.       b.SetComponent(a);  
  56.       b.Opration();  
  57.    }  

 3、例子,再使用装饰模式解决汽车增加GPS等的问题。

[csharp] view plaincopyprint?
  1. public class Car  
  2.     {  
  3.         private string name;  
  4.         public string Name  
  5.         {  
  6.             get { return name; }  
  7.             set { name = value; }  
  8.         }  
  9.           
  10.         public Car()  
  11.         {  
  12.         }  
  13.         public Car(string cName)  
  14.         {  
  15.             this.name = cName;  
  16.         }  
  17.   
  18.         //其余属性略  
  19.         public virtual void CarDescription()  
  20.         {  
  21.             Console.WriteLine("  装饰的汽车“{0}”。", name);  
  22.         }  
  23.     }  
  24.   
  25.     public abstract class DecoratorCar:Car  
  26.     {  
  27.         protected Car car;  
  28.         public void Decorator(Car dcar)  
  29.         {  
  30.            car = dcar;  
  31.         }  
  32.   
  33.         public override void CarDescription()  
  34.         {  
  35.             if (car != null)  
  36.                 car.CarDescription();  
  37.         }  
  38.     }  
  39.   
  40.     //GPSCar  
  41.     public class GPSCar : DecoratorCar  
  42.     {  
  43.         string gStr = "先进的GPS系统 ";  
  44.         public override void CarDescription()  
  45.         {  
  46.             Console.Write(gStr);  
  47.             base.CarDescription();  
  48.         }  
  49.     }  
  50.   
  51.     //TransmitterCar  
  52.     public class TransmitterCar : DecoratorCar  
  53.     {  
  54.         string tStr = "卫星对讲机系统 ";  
  55.         public override void CarDescription()  
  56.         {  
  57.             Console.Write(tStr);  
  58.             base.CarDescription();  
  59.         }  
  60.     }  
  61.   
  62.     //Movies  
  63.     public class MoviesCar : DecoratorCar  
  64.     {  
  65.         string mStr = "先进的影视系统 ";  
  66.         public override void CarDescription()  
  67.         {  
  68.             Console.Write(mStr);  
  69.             base.CarDescription();  
  70.         }  
  71.     }     

    调用:

[csharp] view plaincopyprint?
  1.  static void Main(string[] args)  
  2.         {  
  3.             Car car = new Car("奔驰520");  
  4.   
  5.             GPSCar gCar = new GPSCar();  
  6.             TransmitterCar tCar = new TransmitterCar();  
  7.             MoviesCar mCar = new MoviesCar();  
  8.   
  9.             gCar.Decorator(car);  
  10.             tCar.Decorator(gCar);  
  11.             mCar.Decorator(tCar);  
  12.   
  13.             mCar.CarDescription();  
  14.   
  15.             Console.ReadLine();  
  16.         }  
  17.   
  18.     

  最终显示结果:

 

  我觉得装饰模式逻辑比较清晰一些,如果用继承来实现,继承Car,扩展一个方法装饰GPS,这就成了一个有GPS的车。如果过几天GPS要拆掉处理起来就有些说不通了。而对于汽车来说,只要不是它的固有属性(轮子,发动机,方向盘等)的都可视为是装饰品。装饰模式将这些用于装饰的东西,封装成一个一个的类,可以随时拿来使用也可以去掉,比较方便一些。

0 0