结构型模式关注如何将现有类或对象组织一起形成更加强大的结构。
一、概述
在IO流 中,我们经常可以看到这种代码:
new BufferedInputStream(new FileInputStream("D:/xxx.text"));
而这两个类却是同一个类的子类:
BufferedInputStream 为 InputStream增加了缓冲区,这就是装饰者模式的典型应用实例。
装饰者模式的应用不仅仅体现在 IO流 中,在 Mybatis 的 Cache 缓存模块中也有体现:
装饰者模式用于替代继承,它无须定义子类以向对象动态增加职责,使用关联关系取代继承关系。
装饰者模式(Decorator Pattern):动态地给一个对象增加一些额外的职责。就扩展功能而言,装饰模式提供了一种比使用子类更加灵活的替代方案。
二、结构
- Component(抽象构件):
具体构件、抽象装饰类的共同父类,声明具体构件实现的业务方法。 - ConcreteComponent(具体构件):
抽象构件类的子类,实现在抽象构件中的方法,装饰类可以为它赋予额外职责(方法)。 - Decorator(抽象装饰类):
抽象构件类的子类,用于为具体构件增加职责,但是具体职责由其子类实现。 - ConcreteDecorator(具体装饰类):
抽象装饰类的子类,负责向构件添加具体功能以扩充对象行为。
三、举例实现
背景:一款手机构成包含摄影组件(Component),其中之一就是镜头(Camera),而我们在拥有镜头的基础上可以为其增加美颜(RetouchDecorator)、滤镜(FilterDecorator)特效(CameraDecorator)。
摄影组件类:充当抽象构件的角色
//摄影组件类
public abstract class Component {
public abstract void takePhoto();
}
相机类:充当具体构建的角色
//相机类
public class Camera extends Component {
@Override
public void takePhoto() {
System.out.println("拍照片");
}
}
相机装饰类:充当抽象装饰类的角色
//相机装饰类
public class CameraDecorator extends Component {
//装饰对象:具体装饰类须包装该组件
private Component component;
//通过装饰器传入组件,保证包装顺利进行
public CameraDecorator(Component component) {
this.component = component;
}
//调用拍照方法
@Override
public void takePhoto() {
component.takePhoto();
}
}
滤镜功能类:充当具体装饰类的角色
//滤镜功能
public class FilterDecorator extends CameraDecorator{
//构造器
public FilterDecorator(Component component) {
super(component);
}
//包装
@Override
public void takePhoto() {
//执行特殊操作
this.filter();
//执行原操作
super.takePhoto();
}
//特殊操作
public void filter(){
System.out.println("滤镜过滤");
}
}
美颜功能类:充当具体装饰类的角色
//美颜功能
public class RetouchDecorator extends CameraDecorator{
//构造器
public RetouchDecorator(Component component) {
super(component);
}
//包装
@Override
public void takePhoto() {
//执行特殊操作
this.beautify();
//执行原操作
super.takePhoto();
}
//特殊操作
public void beautify(){
System.out.println("美颜效果");
}
}
四、特点
☯ 优点
- 功能扩展灵活,类的数量较少
- 可动态地扩展对象的功能,通过配置文件可以对行为进行选择
- 可多次装饰对象,通过不同具体装饰类,排列组合出更强大的对象
- 具体装饰类可独立变化,不影响其他代码,符合开闭原则
☯ 缺点
- 在使用装饰模式进行系统设计,会产生很多小对象,它们的却别在于之间的连接方式不同
- 装饰模式比继承更加灵活,但更易于出错,须逐级排查