定义:动态地给一个对象添加一些额外的职责。就增加功能来说,
Decorator
模式相比生成子类更为灵活。
类型:结构型模式。
类图:
参入者:
- Component,抽象类,只是提供接口。
- Model,一个具体对象,实现接口完成一些基本的功能。
- Decorator,有一个指向Component的指针,并且实现了Componet的接口。
- Hairtician,Costumer,都是具体的装饰者,首先在实现基本的接口下,添加了新的功能。
适用性:
- 装饰模式其应用体现在装饰上。那些需要动态添加同类型功能的产品,都可以使用装饰模式。
- 以添加新类的方式来给单个对象添加新装饰。
- 当不能以子类的方式扩展时,可以使用装饰模式来扩展。
概述:
装饰者模式是一种结构模式,表明装饰者模式主要是通过更改类的结构关系来实现的。Decorator与Model保持相同的接口,主要是为了保证操作Hairtician和Costumer时保持和操作Model时一样的体验。理论上来说,Decorator和Model不保持一样的接口,重新定义接口也是可以的。这里的装饰是一种链式的,即每一种新添加的装饰都是在之前的基本上生成新的类来完成的。新类在完成新添加的装饰之后,然后将接下来的动作返还到上一个装饰者。依次这样,达到链式完成装饰的功能。因为保持接口一致,在客户看来,其实是一致的,不影响客户的调用及体验。
示例代码:
// C#
namespace
Design10
{
class
Component
{
public
virtual
void
MakeUp
(
)
{
}
}
class
Model
:
Component
{
public
override
void
MakeUp
(
)
{
Console
.
WriteLine
(
"
模特自己完成基本的装扮
"
)
;
}
}
abstract
class
Decorator
:
Component
{
protected
Component
component
;
public
void
SetComponent
(
Component
component
)
{
this
.
component
=
component
;
}
public
override
void
MakeUp
(
)
{
if
(
component
!=
null
)
{
component
.
MakeUp
(
)
;
}
}
}
class
Hairtician
:
Decorator
{
public
override
void
MakeUp
(
)
{
base
.
MakeUp
(
)
;
Console
.
WriteLine
(
"
做新的发型
"
)
;
}
}
class
Costumer
:
Decorator
{
public
override
void
MakeUp
(
)
{
base
.
MakeUp
(
)
;
AddedBehavior
(
)
;
}
private
void
AddedBehavior
(
)
{
Console
.
WriteLine
(
"
穿个性化的裙子
"
)
;
}
}
class
Program
{
static
void
Main
(
string
[
]
args
)
{
Model
model
=
new
Model
(
)
;
Decorator
decorator1
=
new
Hairtician
(
)
;
Decorator
decorator2
=
new
Costumer
(
)
;
decorator1
.
SetComponent
(
model
)
;
decorator2
.
SetComponent
(
decorator1
)
;
decorator2
.
MakeUp
(
)
;
}
}
}
与其他模式比较:装饰者模式其实与组合模式有一些类似的地方。都是通过组合的方法来实现添加新的模块。只是装饰者模式将产品独立出来,抽象出来装饰这个动作。而组合模式没有将产品与动作分开,组合模式的链条可以是像装饰者模式模式那样单一链条,也可是树形的,分出多个分支。
注意:
- 如果是C++代码需要注意抽象类的析构函数必须是虚函数,否则释放内存的时候会出现问题。
- C#,Java的时候,最开始的接口类不能改为接口,这样多态在经过多次继承之后会出现问题。
优缺点:
- 优点,动态添加新功能,能够组合不同的功能,并且保证接口的一致。
- 缺点,如果添加的功能过多,会增加过多的类,增加程序复杂度。
参考资料:
- 《设计模式——可复用面向对象软件基础》
- 《Java与模式》
- 《大话设计模式》
- 《Head First设计模式》