设计模式-装饰者模式
定义:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰者模式比生成子类更灵活。
特点:
(1) 装饰对象和真实对象有相同的接口
(2)装饰对象包含一个真实对象的引用
(3)装饰对象接受所有来自客户的请求,然后把请求转发给真实对象,在转发请求之前或者以后增加一些附加功能,以达到在运行时,不用修改具体对象的结构就可以对其增加附加的功能
装饰者模式的使用场景
(1) 需要扩展一个类的功能,或给一个类增加附加功能
(2) 需要动态地给一个对象增加功能,这些功能可以动态地撤销
(3) 需要为一批的兄弟类进行改装或加装功能
装饰者模式类图如下
Component 抽象角色
是一个接口或者是抽象类,就是定义我们最核心的对象
ConcreteComponent 具体角色
抽象角色接口或抽象类的实现,需要装饰的对象
Decorate 装饰角色
一般是一个抽象类,实现接口或者抽象方法,它一定要有一个 Component 对象的引用
Concrete Decorator 具体装饰角色
动态地对 具体角色添加职责
有钱了要买大别墅,买了大别墅需要装修设计,怎么设计呢???
代码如下
Component 抽象角色
// 房子接口
public interface IHouse
{
// 房屋设计
void Design();
}
ConcreteComponent 具体角色
// 大别墅
public class Villa : IHouse
{
// 房屋设计
public void Design()
{
Console.WriteLine("设计成这个样子");
}
}
Decorate 装饰角色
// 抽象装饰角色
public class Decorator : IHouse
{
private IHouse _house;
public Decorator(IHouse house)
{
_house = house;
}
// 房屋设计
public virtual void Design()
{
_house.Design();
}
}
Concrete Decorator 具体装饰角色
public class SofaDecorator : Decorator
{
public SofaDecorator(IHouse house) : base(house)
{
}
// 房屋设计
public override void Design()
{
base.Design();
Console.WriteLine("放一个大沙发");
}
}
// TV 设计
public class TVDecorator : Decorator
{
public TVDecorator(IHouse house) : base(house)
{
}
// 房屋设计
public override void Design()
{
base.Design();
Console.WriteLine("装一个65寸大彩电");
}
}
// 吊灯设计
public class CeilingLampDecorator : Decorator
{
public CeilingLampDecorator(IHouse house) : base(house)
{
}
// 房屋设计
public override void Design()
{
base.Design();
Console.WriteLine("客厅装一个大吊灯");
}
}
调用如下
public class Client
{
public Client()
{
// 买一个大别墅
IHouse house = new Villa();
// 沙发设计
house = new SofaDecorator(house);
// TV 设计
house = new TVDecorator(house);
// 大吊灯设计
house = new CeilingLampDecorator(house);
house.Design();
}
}
运行结果如下
优点:
(1) 装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性
(2) 通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出多种不同的组合。
(3) 装饰类和被装饰类可以独立发展,而不相互耦合
缺点:
(1) 这种比继承更灵活的特点,同时意味着更多的复杂性
(2) 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂