给对象增加新功能,如何实现:
(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要拆掉处理起来就有些说不通了。而对于汽车来说,只要不是它的固有属性(轮子,发动机,方向盘等)的都可视为是装饰品。装饰模式将这些用于装饰的东西,封装成一个一个的类,可以随时拿来使用也可以去掉,比较方便一些。