IE盒子

搜索
查看: 181|回复: 1

Java 装饰模式讲解和代码示例

[复制链接]

4

主题

5

帖子

13

积分

新手上路

Rank: 1

积分
13
发表于 2022-9-23 20:08:05 | 显示全部楼层 |阅读模式
使用示例:装饰在 Java 代码中可谓是标准配置,尤其是在与流式加载相关的代码中。
Java 核心程序库中有一些关于装饰的示例:

  • java.io.InputStream、Output­Stream、Reader和Writer的所有代码都有以自身类型的对象作为参数的构造函数。
  • java.util.Collections;checked­XXX()、synchronized­XXX()和unmodifiable­XXX()方法。
  • javax.servlet.http.HttpServletRequestWrapper和Http­Servlet­Response­Wrapper
识别方法:装饰可通过以当前类或对象为参数的创建方法或构造函数来识别。
01
编码和压缩装饰
本例展示了如何在不更改对象代码的情况下调整其行为。
最初的业务逻辑类仅能读取和写入纯文本的数据。此后,我们创建了几个小的封装器类,以便在执行标准操作后添加新的行为。
第一个封装器负责加密和解密数据,而第二个则负责压缩和解压数据。
你甚至可以让这些封装器嵌套封装以将它们组合起来。
02
decorators
decorators/DataSource.java:定义了读取和写入操作的通用数据接口

package refactoring_guru.decorator.example.decorators;public interface DataSource {    void writeData(String data);    String readData();}decorators/FileDataSource.java:简单数据读写器

package refactoring_guru.decorator.example.decorators;import java.io.*;public class FileDataSource implements DataSource {    private String name;    public FileDataSource(String name) {        this.name = name;    }    @Override    public void writeData(String data) {        File file = new File(name);        try (OutputStream fos = new FileOutputStream(file)) {            fos.write(data.getBytes(), 0, data.length());        } catch (IOException ex) {            System.out.println(ex.getMessage());        }    }    @Override    public String readData() {        char[] buffer = null;        File file = new File(name);        try (FileReader reader = new FileReader(file)) {            buffer = new char[(int) file.length()];            reader.read(buffer);        } catch (IOException ex) {            System.out.println(ex.getMessage());        }        return new String(buffer);    }}decorators/DataSourceDecorator.java:抽象基础装饰

package refactoring_guru.decorator.example.decorators;public class DataSourceDecorator implements DataSource {    private DataSource wrappee;    DataSourceDecorator(DataSource source) {        this.wrappee = source;    }    @Override    public void writeData(String data) {        wrappee.writeData(data);    }    @Override    public String readData() {        return wrappee.readData();    }}decorators/EncryptionDecorator.java:加密装饰

package refactoring_guru.decorator.example.decorators;import java.util.Base64;public class EncryptionDecorator extends DataSourceDecorator {    public EncryptionDecorator(DataSource source) {        super(source);    }    @Override    public void writeData(String data) {        super.writeData(encode(data));    }    @Override    public String readData() {        return decode(super.readData());    }    private String encode(String data) {        byte[] result = data.getBytes();        for (int i = 0; i < result.length; i++) {            result += (byte) 1;        }        return Base64.getEncoder().encodeToString(result);    }    private String decode(String data) {        byte[] result = Base64.getDecoder().decode(data);        for (int i = 0; i < result.length; i++) {            result -= (byte) 1;        }        return new String(result);    }}decorators/CompressionDecorator.java:压缩装饰

package refactoring_guru.decorator.example.decorators;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.util.Base64;import java.util.zip.Deflater;import java.util.zip.DeflaterOutputStream;import java.util.zip.InflaterInputStream;public class CompressionDecorator extends DataSourceDecorator {    private int compLevel = 6;    public CompressionDecorator(DataSource source) {        super(source);    }    public int getCompressionLevel() {        return compLevel;    }    public void setCompressionLevel(int value) {        compLevel = value;    }    @Override    public void writeData(String data) {        super.writeData(compress(data));    }    @Override    public String readData() {        return decompress(super.readData());    }    private String compress(String stringData) {        byte[] data = stringData.getBytes();        try {            ByteArrayOutputStream bout = new ByteArrayOutputStream(512);            DeflaterOutputStream dos = new DeflaterOutputStream(bout, new Deflater(compLevel));            dos.write(data);            dos.close();            bout.close();            return Base64.getEncoder().encodeToString(bout.toByteArray());        } catch (IOException ex) {            return null;        }    }    private String decompress(String stringData) {        byte[] data = Base64.getDecoder().decode(stringData);        try {            InputStream in = new ByteArrayInputStream(data);            InflaterInputStream iin = new InflaterInputStream(in);            ByteArrayOutputStream bout = new ByteArrayOutputStream(512);            int b;            while ((b = iin.read()) != -1) {                bout.write(b);            }            in.close();            iin.close();            bout.close();            return new String(bout.toByteArray());        } catch (IOException ex) {            return null;        }    }}Demo.java:客户端代码

package refactoring_guru.decorator.example;import refactoring_guru.decorator.example.decorators.*;public class Demo {    public static void main(String[] args) {        String salaryRecords = "Name,Salary\nJohn Smith,100000\nSteven Jobs,912000";        DataSourceDecorator encoded = new CompressionDecorator(                                         new EncryptionDecorator(                                             new FileDataSource("out/OutputDemo.txt")));        encoded.writeData(salaryRecords);        DataSource plain = new FileDataSource("out/OutputDemo.txt");        System.out.println("- Input ----------------");        System.out.println(salaryRecords);        System.out.println("- Encoded --------------");        System.out.println(plain.readData());        System.out.println("- Decoded --------------");        System.out.println(encoded.readData());    }}OutputDemo.txt:执行结果

- Input ----------------Name,SalaryJohn Smith,100000Steven Jobs,912000- Encoded --------------Zkt7e1Q5eU8yUm1Qe0ZsdHJ2VXp6dDBKVnhrUHtUe0sxRUYxQkJIdjVLTVZ0dVI5Q2IwOXFISmVUMU5rcENCQmdxRlByaD4+- Decoded --------------Name,SalaryJohn Smith,100000Steven Jobs,912000
END
回复

使用道具 举报

2

主题

11

帖子

21

积分

新手上路

Rank: 1

积分
21
发表于 2025-4-17 13:23:11 | 显示全部楼层
元芳你怎么看?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表