3. 装饰者
3.1 定义
对于不同功能之间的多种复杂的对象如果使用继承的方式,类的数量将会碰撞,而采用组合的方式,这样就可以在运行时实现不同的功能的组合。
装饰者模式可以动态的将职责附加到对象上。对于扩展功能的情况,提供了比继承更有弹性的解决方案。
看一下具体的实现。类图如下图所示。
Component是一个组件的抽象类,需要被装饰的组件和装饰者都需要实现该抽象类,该抽象类中的方法就是客户端需要调用的方法。
装饰者模式中的关键是装饰者Decorator需要持有一个组件对象Component的引用,这样其他的装饰者实现,可以引用上一层的引用,形成一个层层包裹的状态。
这样,在最外层的装饰者中调用方法,就会层层进入,从内向外一层一层的调用方法。装饰者可以控制方法的行为,在上一层的方法调用之后,加上自身的装饰实现。
3.2 举例
SimpleImage是阿里巴巴的一个Java图片处理的类库,可以实现图片缩略、水印等处理。
SimpleImage中的ImageRender是图片处理的基类,它是一个抽象类,我们看到,该类中定义了一个抽象方法render(),同时持有一个对ImageRender类的引用。
ReadRedner可以理解成一个组件,不是一个装饰者,因为ReadRender是所有渲染操作的第一步。
其他的子类DrawTextRender(水印处理),ScaleRender(缩略处理),WriterRender(输出)都是装饰者。
拿ScaleRender为例子,看一下它的render()类的实现。红色区域的内容,是上一层包装的实现调方法render()的调用,之后的操作是ScaleRender需要关注的图片缩略处理。
客户端的调用如下所示。ReadRender需要引入一个输入流,ScaleRender包裹ReadRender,WriteRender包裹ScaleRender,最后调用最外层的render()方法,处理图像处理,层层进入,
首先ReadRender读取图片数据,ScaleRender进行图片缩略,WriteReneder将处理之后的图片数据写入输出流中,完成一系列操作。