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