设计模式-结构型模式-装饰器模式

1.装饰器模式定义

装饰器模式动态的给一个对象添加一些额外的职责,就扩展功能而言,装饰器模式提供了一种比子类更加灵活的方案;

在软件设计中,装饰器模式是一种用于替代继承的技术,通过一种无需定义子类的方式给对象动态的增加职责,使用对象之间的关联关系取代类之间的继承关系;

1.1 装饰器模式的优缺点

优点

  • 对于扩展一个对象的功能,装饰器模式比继承更加灵活,不会导致类的个数急剧增加;
  • 可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的具体装饰类,从而实现不同的行为;
  • 可以对一个对象进行多次装饰,通过使用不同的具体装饰类以及这些装饰类的排列组合可以创造出很多不同行为的组合,得到更加强大的对象;
  • 具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,原有类库代码无需改变,符合开闭原则;

缺点

  • 在使用装饰器模式进行系统设计时将产生很多小对象,这些对象他们之间的相互连接方式有所不同,而不是他们的类或者属性值不同,大量的小对象的产生要占用更多的系统资源;
  • 装饰器模式提供了一种比继承更加灵活、机动的解决方案,但也意味着比继承更容易出错,排错也更困难,对于多次装饰的对象,在调试寻找错误时可能需要逐级排查,比较麻烦;

1.2 装饰器模式的使用场景

  • 快速动态扩展和撤销一个类的功能场景,如某些时候要求较高的接口安全性,这时候就可以用装饰器模式对传输的数据进行加密;
  • 不支持继承扩展类的场景,如使用final关键字的类,或者系统中存在大量通过继承产生的子类;

2.装饰器模式的原理

  • 抽象构件类(Component):具体构件和抽象装饰类的共同父类,声明了在具体构件中实现的业务方法,引进了可以使客户端以一致的方式处理未被装饰的对象以及装饰之后的对象,实现客户端的透明操作;
  • 具体构件类(Concrete Component):抽象构件类的子类,用于定义具体的构件对象,实现了在抽象构件中声明的方法,装饰类可以给它增加额外的职责;
  • 抽象装饰类(Decorator):是抽象构件类的子类,用于给具体构件增加职责,但是具体职责在其子类中实现,它维护了一个指向抽象构件对象的引用,通过该引用可以调用装饰之前构件对象的方法,并通过子类扩展该方法,以达到装饰的目的;
  • 具体装饰类(ConcreteDecorator):是抽象装饰类的子类,负责向构件添加新的职责,每一个具体装饰类都定义了一些新的行为,它可以调用在抽象装饰类中定义的方法,并可以增加新的方法用于扩充对象的行为;

3.装饰器模式的实现

【实例】

一个文件读写器为例

【代码】

DataLoader:抽象的文件读取接口

java 复制代码
public interface DataLoader {

    String read();

    void write(String data);
}

BaseFileDataLoader:重写DataLoader的读写方法;

java 复制代码
public class BaseFileDataLoader implements DataLoader {

    private String filePath;

    public BaseFileDataLoader(String filePath) {
        this.filePath = filePath;
    }

    @Override
    public String read() {

        try {
            String result = FileUtils.readFileToString(new File(filePath), "utf-8");
            return result;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public void write(String data) {
        try{
            FileUtils.writeStringToFile(new File(filePath), data, "utf-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

DataLoaderDecorator:包含一个引用DataLoader的对象实例wrapper,同样是重写DataLoader方法,不过这里使用wrapper来读写,不进行扩展;

java 复制代码
public class DataLoaderDecorator implements DataLoader {

    private DataLoader wrapper;

    public DataLoaderDecorator(DataLoader wrapper) {
        this.wrapper = wrapper;
    }

    @Override
    public String read() {
        return wrapper.read();
    }

    @Override
    public void write(String data) {
        wrapper.write(data);
    }
}

EncryptionDataDecorator:读写时有加解密功能的具体装饰器,继承了装饰器DataLoader Decorator重写读写方法;

java 复制代码
public class EncryptionDataDecorator extends DataLoaderDecorator {
    public EncryptionDataDecorator(DataLoader wrapper) {
        super(wrapper);
    }
    @Override
    public String read() {
        return decode(super.read());
    }
    @Override
    public void write(String data) {
        super.write(encode(data));
    }
    //加密操作
    private String encode(String data) {
        try {
             Base64.Encoder encoder = Base64.getEncoder();
             byte[] bytes = data.getBytes("UTF-8");
             String result = encoder.encodeToString(bytes);
             return result;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    //解密
    private String decode(String data) {
        try {
            Base64.Decoder decoder = Base64.getDecoder();
            String result = new String(decoder.decode(data), "UTF-8");
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

客户端

java 复制代码
DataLoaderDecorator decorator = new EncryptionDataDecorator(new BaseFileDataLoader("demo.txt"));
decorator.write(info);

String data = decorator.read();
System.out.println(data);
相关推荐
桦说编程31 分钟前
CompletableFuture 超时功能有大坑!使用不当直接生产事故!
java·性能优化·函数式编程·并发编程
@_@哆啦A梦34 分钟前
Redis 基础命令
java·数据库·redis
字节全栈_rJF1 小时前
性能测试 —— Tomcat监控与调优:status页监控_tomcat 自带监控
java·tomcat
爱编程的小新☆3 小时前
Java篇之继承
java·开发语言
gentle coder3 小时前
Redis_Redission的入门案例、多主案例搭建、分布式锁进行加锁、解锁底层源码解析
java·redis·分布式
萝卜青今天也要开心3 小时前
读书笔记-《Redis设计与实现》(一)数据结构与对象(下)
java·数据结构·redis·学习
customer083 小时前
【开源免费】基于SpringBoot+Vue.JS景区民宿预约系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
太阳伞下的阿呆3 小时前
排查定位jar包大文件
java·centos·jar
MyY_DO3 小时前
maven mysql jdk nvm node npm 环境安装
java·mysql·maven
带刺的坐椅4 小时前
无耳科技 Solon v3.0.7 发布(2025农历新年版)
java·spring·mvc·solon·aop