蚂蚁课堂第5期-互联网架构-004:装饰者模式
1 装饰者设计模式的简单介绍
课题内容:
1.什么是装饰者模式
2.装饰者模式与责任链模式区别
3.两种方式创建装饰者模式
4.根据源码分析装饰者模式原理
什么是装饰者模式
在不改变原有对象的基础上附加功能,相比生成子类更灵活。
装饰者模式应用场景
动态的给一个对象添加或者撤销功能。
装饰者模式优缺点
优点:可以不改变原有对象的情况下动态扩展功能,可以使扩展的多个功能按想要的顺序执行,以实现不同效果。
缺点:更多的类,使程序复杂
举例:使用网关实现API接口安全控制
1.获取基本网关参数… HttpServletRequest
2.下面继续实现的操作 后面可能会新增。
----2.1 网关中新增日志收集
----2.2 网关中新增API接口限流
2 装饰设计模式类图结构01
装饰者模式定义
(1) 抽象组件:定义一个抽象接口,来规范准备附加功能的类
(2) 具体组件:将要被附加功能的类,实现抽象构件角色接口
(3) 抽象装饰者:持有对具体构件角色的引用并定义与抽象构件角色一致的接口
(4) 具体装饰:实现抽象装饰者角色,负责对具体构件添加额外功能。
protected ComponentGateway componentGateway;
setComponentGateway(ComponentGateway componentGateway)
3 装饰设计模式类图结构02
4 装饰设计模式第一种写法
1.定义一个抽象的组件 GatewayComponent
public abstract class GatewayComponent {
/**
* 定义共同附加行为方法标准
*/
public abstract void service();
}
2.定义被装饰角色 BasicGatewayComponent
public class BasicGatewayComponent extends GatewayComponent {
@Override
public void service() {
System.out.println("第一步>> 获取网关中基本的参数..");
}
}
3.定义抽象装饰角色 AbstractDecorator
public class AbstractDecorator extends GatewayComponent{
@Override
public void service() {}
}
4.定义具体装饰角色 LogDecorator/LimitDecorator
public class LogDecorator extends AbstractDecorator {
private GatewayComponent gatewayComponent;
@Override
public void service() {
if (gatewayComponent != null) {
gatewayComponent.service();
}
System.out.println("第二步>> 网关中新增日志收集..");
}
public void setGatewayComponent(GatewayComponent gatewayComponent) {
this.gatewayComponent = gatewayComponent;
}
}
public class LimitDecorator extends AbstractDecorator {
private GatewayComponent gatewayComponent;
@Override
public void service() {
if (gatewayComponent != null) {
gatewayComponent.service();
}
System.out.println("第三步>> 网关中新增API接口的限流..");
}
public void setGatewayComponent(GatewayComponent gatewayComponent) {
this.gatewayComponent = gatewayComponent;
}
}
5.使用工厂获取装饰类 FactoryGateway
public class FactoryGateway {
public static GatewayComponent getGatewayComponent(){
// 1.创建日志装饰类
LogDecorator logDecorator = new LogDecorator();
LimitDecorator limitDecorator = new LimitDecorator();
limitDecorator.setGatewayComponent(logDecorator);
// 2.创建被装饰实现类
BasicGatewayComponent basicGatewayComponent = new BasicGatewayComponent();
logDecorator.setGatewayComponent(basicGatewayComponent);
return limitDecorator;
}
public static void main(String[] args){
GatewayComponent gatewayComponent = FactoryGateway.getGatewayComponent();
gatewayComponent.service();
}
}
执行结果:
5 装饰设计模式第二种写法
AbstractDecorator
public class AbstractDecorator extends GatewayComponent {
public GatewayComponent gatewayComponent;
public AbstractDecorator(GatewayComponent gatewayComponent) {
this.gatewayComponent = gatewayComponent;
}
@Override
public void service() {
if (gatewayComponent != null) {
gatewayComponent.service();
}
}
}
LogDecorator/LimitDecorator
public class LogDecorator extends AbstractDecorator {
public LogDecorator(GatewayComponent gatewayComponent) {
super(gatewayComponent);
}
@Override
public void service() {
super.service();
System.out.println("第二步>> 网关中新增日志收集..");
}
}
public class LimitDecorator extends AbstractDecorator {
public LimitDecorator(GatewayComponent gatewayComponent) {
super(gatewayComponent);
}
@Override
public void service() {
super.service();
System.out.println("第三步>> 网关中新增API接口的限流..");
}
}
FactoryGateway
public class FactoryGateway {
public static GatewayComponent getGatewayComponent() {
return new LimitDecorator(new LogDecorator(new BasicGatewayComponent()));
}
public static void main(String[] args) {
GatewayComponent gatewayComponent = FactoryGateway.getGatewayComponent();
gatewayComponent.service();
}
}
6 IO流装饰模式源码分析
Java I/O 中的装饰者模式
它基于字符流(InputStream/OutputStream)和字节流(Reader/Writer)作为基类。
抽象构造角色 Reader
FilterReader 抽象的装饰类
InputStreamReader 具体的装饰类
责任链与装饰模式区别
责任链实现原理:
通过指向下一个handler的方法 顺序依据链表…责任链是顺序的执行,指向下一个节点 (正向流程)。
每个被调用者都持有下一个被调用者的引用,客户端只需要发起一次调用即可。
应用场景:过滤器、网关控制权限、p2p风控审批
装饰的实现原理:
通过super执行具体的被装饰类,再反向从装饰类开始执行… (反向流程)。
持有被装饰的对象,并具备被装饰者的行为,对其行为进行补充增强
应用场景:io流、Spring Session、mybatis多级缓存