|
使用示例:装饰在 Java 代码中可谓是标准配置,尤其是在与流式加载相关的代码中。
Java 核心程序库中有一些关于装饰的示例:
- java.io.InputStream、OutputStream、Reader和Writer的所有代码都有以自身类型的对象作为参数的构造函数。
- java.util.Collections;checkedXXX()、synchronizedXXX()和unmodifiableXXX()方法。
- javax.servlet.http.HttpServletRequestWrapper和HttpServletResponseWrapper
识别方法:装饰可通过以当前类或对象为参数的创建方法或构造函数来识别。
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 = &#34;Name,Salary\nJohn Smith,100000\nSteven Jobs,912000&#34;; DataSourceDecorator encoded = new CompressionDecorator( new EncryptionDecorator( new FileDataSource(&#34;out/OutputDemo.txt&#34;))); encoded.writeData(salaryRecords); DataSource plain = new FileDataSource(&#34;out/OutputDemo.txt&#34;); System.out.println(&#34;- Input ----------------&#34;); System.out.println(salaryRecords); System.out.println(&#34;- Encoded --------------&#34;); System.out.println(plain.readData()); System.out.println(&#34;- Decoded --------------&#34;); System.out.println(encoded.readData()); }}OutputDemo.txt:执行结果
- Input ----------------Name,SalaryJohn Smith,100000Steven Jobs,912000- Encoded --------------Zkt7e1Q5eU8yUm1Qe0ZsdHJ2VXp6dDBKVnhrUHtUe0sxRUYxQkJIdjVLTVZ0dVI5Q2IwOXFISmVUMU5rcENCQmdxRlByaD4+- Decoded --------------Name,SalaryJohn Smith,100000Steven Jobs,912000
END |
|