1、什么是装饰者模式
装饰者模式就是在不改变原有对象的基础上附加功能,相比生成子类更灵活。
2、装饰者模式应用场景
1.在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
2.需要动态地给一个对象增加功能,这些功能也可以动态地被撤销。当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。
3、装饰者模式优缺点
优点:可以不改变原有对象的情况下动态扩展功能,可以使扩展的多个功能按想要的顺序执行,以实现不同效果。
缺点:更多的类,使程序复杂
4、装饰者模式类图
5、装饰者模式定义
(1)抽象组件:定义一个抽象接口,来规范准备附加功能的类
(2)具体组件:将要被附加功能的类,实现抽象构件角色接口
(3)抽象装饰者:持有对具体构件角色的引用并定义与抽象构件角色一致的接口
(4)具体装饰:实现抽象装饰者角色,负责对具体构件添加额外功能。
6、装饰者模式代码实现
抽象构建角色
/**
* @Classname GatewayComponment
* @Description 抽象构建角色
* @Date 2019/5/21 10:31
* @Created by mark
*/
public abstract class GatewayComponent {
/**
* 定义共同附加行为的方法标准..
*/
public abstract void service();
}
被装饰角色
public class BasicGatewayComponent extends GatewayComponent {
@Override
public void service() {
System.out.println("第一步>>> 网关中获取基本的操作...");
}
}
抽象装饰角色
public abstract class AbstractDecorator extends GatewayComponent {
private GatewayComponent gatewayComponent;
public AbstractDecorator(GatewayComponent gatewayComponment) {
this.gatewayComponent = gatewayComponment;
}
@Override
public void service() {
if (gatewayComponent != null) {
gatewayComponent.service();
}
}
}
具体装饰角色
LogDecorator.java
public class LogDecorator extends AbstractDecorator {
public LogDecorator(GatewayComponent gatewayComponent) {
super(gatewayComponent);
}
@Override
public void service() {
super.service();
System.out.println("第二步>>> 网关中新增日志收集...");
}
}
LimitDecorator.java
public class LimitDecorator extends AbstractDecorator {
public LimitDecorator(GatewayComponent gatewayComponent) {
super(gatewayComponent);
}
@Override
public void service() {
super.service();
System.out.println("第三步>>> 网关中新增API接口的限流...");
}
}
工厂获取装饰类
public class FactoryGateway {
public static GatewayComponent getGatewayComponent() {
return new LimitDecorator(new LogDecorator(new BasicGatewayComponent()));
}
}
测试类
public class DecorateClient {
public static void main(String[] args) {
GatewayComponent gatewayComponent = FactoryGateway.getGatewayComponent();
gatewayComponent.service();
}
}
运行结果
第一步>>> 网关中获取基本的操作...
第二步>>> 网关中新增日志收集...
第三步>>> 网关中新增API接口的限流...
7、源码角度分析
1、java中的io流
2、Spring Session 中的装饰者模式
3、Mybatis 缓存中的装饰者模式
// java中的io流
BufferedReader in1 = new BufferedReader(new InputStreamReader(new FileInputStream(file)));//字符流
DataInputStream in2 = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));//字节流
// DataInputStream-从数据流读取字节,并将它们装换为正确的基本类型值或字符串
// BufferedInputStream-可以通过减少读写次数来提高输入和输出的速度
8、装饰者模式与责任链模式的区别
责任链实现原理:
每个被调用者 都持有下一个被调用者 的引用,客户端只需要发起一次调用即可。
装饰的实现原理
持有被装饰的对象,并具备被装饰者的行为,对其行为进行补充增强
区别
责任链模式原理:通过指向下一个handler的方法,顺序依据链表执行,指向下一个节点(正向流程)
装饰者模式原理:通过super执行具体被装饰类,再反向从装饰类开始执行(反向流程)