设计模式(十)—— 装饰者模式
模式简介
动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。
装饰者模式又叫包装器模式(Wrapper),它是一种结构型模式。如果一定要一句话或者一件事物来形容,我觉得使用下图来表示这种结构再合适不过了。没错,装饰者模式就是在鸡排上面放一层生菜,生菜上面撒一层沙拉酱,最后用两片面包包起来。
将组件嵌入到一个对象中,由这个对象添加一些功能,我们称这个对象为装饰,装饰与其中嵌入的组件接口一致,因此它对使用该组件的客户透明。它将客户请求转发给该组件,并在转发前后执行一些额外的动作。
结构说明
角色说明
- Component
定义一个对象接口,可以给这些对象动态添加职责。这个接口的主要作用是使Component可以出现的地方都可以有装饰
- ConcreteComponent
定义一个对象,可以给这个对象添加一些职责
- Decorator
装饰者抽象类,包含一个Component对象的成员
- ConcreteDecorator
具体装饰类,为组件添加职责
Decorator将请求转发给它的Compoment对象,并在转发请求前后执行一些附加的操作。
示例分析
这一节我们使用Decorator模式完成本篇开头的示例。首先声明接口IHamburger,包含Make方法,定义Chicken类作为具体构件,实现IHamburger接口。
interface IHamburger
{
void Make();
}
class Chicken : IHamburger
{
public void Make()
{
Console.WriteLine("``````Chicken```````");
}
}
创建抽象装饰者(Decorator):
abstract class HamburgerDecorator : IHamburger
{
protected IHamburger hamburgerToBeDecorated;
public HamburgerDecorator(IHamburger hamburgerToBeDecorated)
{
this.hamburgerToBeDecorated = hamburgerToBeDecorated;
}
public virtual void Make()
{
hamburgerToBeDecorated.Make();
}
}
创建具体装饰者(ConcreteDecorator):
class LettuceDecorator : HamburgerDecorator
{
public LettuceDecorator(IHamburger hamburgerToBeDecorated) : base(hamburgerToBeDecorated)
{
}
public override void Make()
{
Console.WriteLine("~~~~~~~Lettuce~~~~~~");
base.Make();
}
}
class SaladDecorator : HamburgerDecorator
{
public SaladDecorator(IHamburger hamburgerToBeDecorated) : base(hamburgerToBeDecorated)
{
}
public override void Make()
{
Console.WriteLine("=======salad========");
base.Make();
}
}
class BreadDecorator : HamburgerDecorator
{
public BreadDecorator(IHamburger hamburgerToBeDecorated) : base(hamburgerToBeDecorated)
{
}
public override void Make()
{
Console.WriteLine(" .................. ");
Console.WriteLine("....................");
base.Make();
Console.WriteLine("....................");
Console.WriteLine(" .................. ");
}
}
客户端调用:
class Program
{
static void Main(string[] args)
{
Chicken chicken = new Chicken();
LettuceDecorator withLettuce = new LettuceDecorator(chicken);
SaladDecorator withSalad = new SaladDecorator(withLettuce);
BreadDecorator withBread = new BreadDecorator(withSalad);
withBread.Make();
Console.ReadLine();
}
}
输出结果:
使用场景
-
在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责
- 处理那些可以撤销的职责
-
当不能采用生成子类的方法进行扩充时
优缺点
优点
- 比继承更灵活。继承要求给每个添加的职责创建一个新的子类,这会产生很多不必要的类,使用Decorator可以对职责进行组合,减少系统中类的数量。
- 具体构建类和具体装饰类可以独立变化,在使用时再对其组合。
- 可以在运行时动态地增加和删除职责。
缺点
- 使用装饰者模式对系统进行设计时会产生很多具体装饰类以及小对象,这些装饰类和小对象会增加系统的复杂度,使得系统难以理解。