1、背景
给对象增加新功能,如何实现:
(1)、在原类里面增加——违背开放封闭原则,类可以扩展但不能被修改。
(2)、利用继承扩展功能——造成类不断增多。
例子:给汽车增加对讲机系统,GPS定位系统,影视播放等,这些都不是汽车类的属性。如何增加?
2、认识装饰模式
装饰模式模型如下:
给对象增加新功能,如何实现:
(1)、在原类里面增加——违背开放封闭原则,类可以扩展但不能被修改。
(2)、利用继承扩展功能——造成类不断增多。
例子:给汽车增加对讲机系统,GPS定位系统,影视播放等,这些都不是汽车类的属性。如何增加?
2、认识装饰模式
装饰模式模型如下:
- 1、Component类
- public abstract class Component
- {
- public abstract void Opration();
- }
- 2、ConcreteComponent类
- public class ConcreteComponent:Component
- {
- public override void Opration()
- {
- //具体对象的操作
- }
- }
- 3、Decorator类
- public abstract class Decorator:ConcreteComponent
- {
- protected Component component;
- public void SetComponent(Component dComponent)
- {
- component = dComponent;
- }
- public override void Opration()
- {
- base.Opration();
- }
- }
- 4、具体的装饰类
- public class ConcreteDecoratorA : Decorator
- {
- private string addState;//本类独有的,区别与ConcreteDecoratorB
- public override void Opration()
- {
- base.Opration();
- addState = "新状态";
- //具体装饰对象A的操作
- }
- }
- public class ConcreteDecoratorB : Decorator
- {
- public override void Opration()
- {
- base.Opration();
- //AddBehavior();
- //具体装饰对象A的操作
- }
- }
- 客户端调用:
- static void Main(string[] args)
- {
- ConcreteComponent c = new ConcreteComponent();
- ConcreteDecoratorA a = new ConcreteDecoratorA();
- ConcreteDecoratorB b = new ConcreteDecoratorB();
- a.SetComponent(c);
- b.SetComponent(a);
- b.Opration();
- }
3、例子,再使用装饰模式解决汽车增加GPS等的问题。
- public class Car
- {
- private string name;
- public string Name
- {
- get { return name; }
- set { name = value; }
- }
- public Car()
- {
- }
- public Car(string cName)
- {
- this.name = cName;
- }
- //其余属性略
- public virtual void CarDescription()
- {
- Console.WriteLine(" 装饰的汽车“{0}”。", name);
- }
- }
- public abstract class DecoratorCar:Car
- {
- protected Car car;
- public void Decorator(Car dcar)
- {
- car = dcar;
- }
- public override void CarDescription()
- {
- if (car != null)
- car.CarDescription();
- }
- }
- //GPSCar
- public class GPSCar : DecoratorCar
- {
- string gStr = "先进的GPS系统 ";
- public override void CarDescription()
- {
- Console.Write(gStr);
- base.CarDescription();
- }
- }
- //TransmitterCar
- public class TransmitterCar : DecoratorCar
- {
- string tStr = "卫星对讲机系统 ";
- public override void CarDescription()
- {
- Console.Write(tStr);
- base.CarDescription();
- }
- }
- //Movies
- public class MoviesCar : DecoratorCar
- {
- string mStr = "先进的影视系统 ";
- public override void CarDescription()
- {
- Console.Write(mStr);
- base.CarDescription();
- }
- }
调用:
- static void Main(string[] args)
- {
- Car car = new Car("奔驰520");
- GPSCar gCar = new GPSCar();
- TransmitterCar tCar = new TransmitterCar();
- MoviesCar mCar = new MoviesCar();
- gCar.Decorator(car);
- tCar.Decorator(gCar);
- mCar.Decorator(tCar);
- mCar.CarDescription();
- Console.ReadLine();
- }
最终显示结果:
我觉得装饰模式逻辑比较清晰一些,如果用继承来实现,继承Car,扩展一个方法装饰GPS,这就成了一个有GPS的车。如果过几天GPS要拆掉处理起来就有些说不通了。而对于汽车来说,只要不是它的固有属性(轮子,发动机,方向盘等)的都可视为是装饰品。装饰模式将这些用于装饰的东西,封装成一个一个的类,可以随时拿来使用也可以去掉,比较方便一些。