文章目录
1.什么是装饰者模式
在不改变原有对象的基础上附加功能,相比生成子类更灵活。(相当于盖楼先有地基再有一楼、再有二楼)
2.装饰者模式应用场景
动态的给一个对象添加或者撤销功能。
3.装饰者模式优缺点
- 优点
可以不改变原有对象的情况下动态扩展功能,可以使扩展的多个功能按想要的顺序执行,以实现不同效果。 - 缺点
更多的类,使程序复杂
4.代码实现装饰模式
4.1 装饰者模式定义
- 抽象组件:定义一个抽象接口,来规范准备附加功能的类
- 具体组件:将要被附加功能的类,实现抽象构件角色接口
- 抽象装饰者:持有对具体构件角色的引用并定义与抽象构件角色一致的接口
- 具体装饰:实现抽象装饰者角色,负责对具体构件添加额外功能。
4.2 装饰者模式类图
4.3 代码实现
4.3.1 规范接口
public interface GatewayComponent {
void service();
}
4.3.2 被装饰者
public class BasicComponentGateway implements GatewayComponent {
public void service() {
System.out.println("第一步>>>>网关开始获取基本参数信息");
}
}
4.3.3 抽象装饰类
//此代码有待优化(不优化可以直接没有此项)
public abstract class AbstractDecorator implements GatewayComponent {
@Override
public void service() {
}
}
4.3.4 具体装饰者
public class LogDecorator extends AbstractDecorator{
private GatewayComponent gatewayComponent;
@Override
public void service() {
// 调用装饰类service
gatewayComponent.service();
// 日志收集
System.out.println("第二步>>>>日志的采集.....");
}
public void setComponentGateway(GatewayComponent gatewayComponent) {
this.gatewayComponent=gatewayComponent;
}
}
public class LimitDecorator extends AbstractDecorator {
private GatewayComponent gatewayComponent;
@Override
public void service() {
// 1.传递日志收集装饰类
gatewayComponent.service();
System.out.println("第三步>>>>API接口限流....");
}
public void setComponentGateway(GatewayComponent gatewayComponent) {
this.gatewayComponent=gatewayComponent;
}
}
4.3.4 使用
public class FactoryGateway {
public static GatewayComponent getComponentGateway() {
LimitDecorator limitDecorator = new LimitDecorator();
LogDecorator logDecorator = new LogDecorator();
limitDecorator.setComponentGateway(logDecorator);
logDecorator.setComponentGateway(new BasicComponentGateway());
return limitDecorator;
}
public static void main(String[] args) {
FactoryGateway.getComponentGateway().service();
}
}
4.3.6 效果
4.3.7 代码优化
由于具体装饰者中代码出现重复可以将代码移到抽象装饰类
public abstract class AbstractDecorator implements GatewayComponent {
private GatewayComponent gatewayComponent;
@Override
public void service() {
gatewayComponent.service();
}
public void setComponentGateway(GatewayComponent gatewayComponent) {
this.gatewayComponent=gatewayComponent;
}
}
public class LimitDecorator extends AbstractDecorator {
@Override
public void service() {
// 1.传递日志收集装饰类
super.service();
System.out.println("第三步>>>>API接口限流....");
}
}
public class LogDecorator extends AbstractDecorator{
@Override
public void service() {
// 调用装饰类service
super.service();
// 日志收集
System.out.println("第二步>>>>日志的采集.....");
}
}
4.3.8 继续优化
使用时代码量较大所以可以借助构造方法实现简化代码
public abstract class AbstractDecorator implements GatewayComponent {
private GatewayComponent gatewayComponent;
public AbstractDecorator(GatewayComponent gatewayComponent){
this.gatewayComponent=gatewayComponent;
}
@Override
public void service() {
gatewayComponent.service();
}
}
public class LimitDecorator extends AbstractDecorator {
public LimitDecorator(GatewayComponent gatewayComponent) {
super(gatewayComponent);
}
@Override
public void service() {
// 1.传递日志收集装饰类
super.service();
System.out.println("第三步>>>>API接口限流....");
}
}
public class LogDecorator extends AbstractDecorator{
public LogDecorator(GatewayComponent gatewayComponent) {
super(gatewayComponent);
}
@Override
public void service() {
// 调用装饰类service
super.service();
// 日志收集
System.out.println("第二步>>>>日志的采集.....");
}
}
public class FactoryGateway {
public static GatewayComponent getComponentGateway() {
return new LimitDecorator(new LogDecorator(new BasicComponentGateway()));
}
public static void main(String[] args) {
FactoryGateway.getComponentGateway().service();
}
}
5.Java I/O 中的装饰者模式
它基于字符流(InputStream/OutputStream) 和 字节流(Reader/Writer)作为基类,下面画出InputStream、Reader的
- 抽象构造角色 Reader
- FilterReader 抽象的装饰类
6.责任链与装饰模式区别
- 责任链实现原理
每个被调用者 都持有下一个被调用者的引用,客户端只需要发起一次调用即可。(指针是从上往下,调用时只需获取第一级) - 装饰的实现原理
持有被装饰的对象,并具备被装饰者的行为,对其行为进行补充增强(指针从下往上,调用时只需要获取最后一级)