先看一个例子: (来自大话设计模式) 设计模式比较晦涩难懂, 个人感觉大话设计模式上的例子比较切近实际, 可以结合大话设计模式和gof一起看.
例子: 一个给人装饰衣物的系统, 类似qq秀的展示,可以有不同的穿衣风格.如 穿裤衩, 西装,打领带,皮靴,运动鞋等,不同风格的组合.
如果定义人的子类的话, 如: 穿西装的人, 穿西装打领带的人..等等,这样会有无数种组合,实现起来是不现实的. 而且如果新增了一种服饰,则会产生n个新的子类.
这时, 我们可以用装饰模式来解决问题.
1. 意图 摘自 gof
动态的给一个对象添加一些额外的职责, 对于添加功能来说. 装饰模式比生成子类更加灵活. 注意; 这里是指给对象 添加一些额外的职责. 也就是说,对于不同的对象,我们可以为其添加不同的装饰,不同的功能.
2. 动机 摘自gof
有时我们希望给某个对象而不是整个类添加新的功能,比如 上例子中,我们想给某个人搭配西装领带,而给另外一个人搭配皮鞋,裤衩,T恤.
使用继承机制添加功能是有效的途径,但是不够灵活, 新增不同的搭配时, 需要有不同的子类支持.
3.适用性
1). 在不影响其他对象的情况下,以动态的,透明的方式给某个对象添加职责.
2). 处理那些可以撤销的职责(不是很理解)
3). 当不能采用生成子类的方式进行扩充时(1. 使用子类扩展会产生大量的子类(如上例子) 2 .类的定义被隐藏, 或者类定义的不能被继承)
4. 结构
6. 参与者
. Component: 定义一个对象接口, 可以给这些对象添加职责.
. ConcreateComponent: 具体的对象实现
. Decorator: 维持一个指向Conponent对象的指针, 并定义一个与Component接口一致的接口
. ConcreateDecorator: 向组件添加职责.
有了这个装饰模式,我们在设计服装系统时, 就灵活的很多了,代码结构图:(摘自大话设计模式)
其中 人扮演的角色是 ConcreateComponent,
服饰类即为Decorator, 嵌入了人的指针.
下面具体的服装,即为ConcreateDecorator. 为某个具体的人对象,添加装饰.
客户端使用代码如下:
Person *p = new Person("name"); suit *s = new suit();
s->setDecorator(p);
s.show();
Tshirt *t = new Tshirt();
t.setDecorator(p)
t.show()