装饰器模式
装饰器模式属于结构型模式
定义:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活
装饰器模式可以为一个现有的类增加新功能,又不改变其结构,要求装饰类和被装饰类实现同一个接口,装饰类持有被装饰类的实例
模式类图
角色
- 抽象接口:
able
接口,最核心组件,被装饰类和装饰类都实现此接口 - 被装饰类:
Source
,要被装饰的类 - 装饰类:
Decorator
,持有Source
类实例,装饰Source
类,为Source
类动态添加新功能
优点
装饰类和被装饰类相互解耦
缺点
多层的装饰比较复杂,减少装饰类的数量,可以降低系统的复杂度
模式代码实现
源码地址:https://github.com/mingyuHub/design-patterns
以打电话为例,涉及Phoneable
(接口),Phone
(被装饰类),Decorator
(装饰类)
抽象接口
被装饰类和装饰类都实现此接口
/**
* @author: chenmingyu
* @date: 2019/3/1 10:20
* @description: 手机接口
*/
public interface Phoneable {
/**
* 打电话
*/
void call();
}
被装饰类
实现Phoneable接口
/**
* @author: chenmingyu
* @date: 2019/3/1 10:19
* @description: 被装饰类
*/
public class Phone implements Phoneable{
@Override
public void call() {
System.out.println("打电话");
}
}
装饰类
实现Phoneable接口,持有被装饰类实例
/**
* @author: chenmingyu
* @date: 2019/3/1 10:26
* @description: 装饰类
*/
public class Decorator implements Phoneable{
private Phone phone;
public Decorator(Phone phone) {
this.phone = phone;
}
@Override
public void call() {
System.out.println("装饰器模式 前置功能:打电话先拨号");
phone.call();
System.out.println("装饰器模式 后置功能:挂断电话");
}
}
验证
public static void main(String[] args) {
Decorator decorator = new Decorator(new Phone());
decorator.call();
}
输出
装饰器模式 前置功能:打电话先拨号
打电话
装饰器模式 后置功能:挂断电话
当我们要拓展一个类的功能时,可以选择使用集成或者装饰器模式,继承的实现是静态,而装饰器模式实现的是动态的,装饰器模式的缺点是会产生很多功能类似的类
参考:设计模式之禅:https://www.kancloud.cn/sstd521/design/193565
推荐阅读:23种设计模式详解