说明
代码复用最好用委托,不要使用继承。
继承是一种紧密耦合,任何父类的改动都会影响子类,不利于系统维护。
实现思想:
通过委托机制,复用系统中的各个组件,在运行时,将这些功能组件进行叠加。
主要做到性能模块分离(组件分离,功能单一)
实现步骤:
1.定义组件接口(装饰者接口)
2.定义装饰者
2.1 实现组件接口
2.2 定义装饰对象
2.3 添加构造函数,传入装饰对象
3.定义 具体的组件、具体的装饰者 实现
4.组装组件
JDK中使用的装饰者模型:
OutputStream 和 InputStream
源码实践
组件接口
package xin.rtime.design.decorate;// 组件接口public interface Component {String operation();}
具体的组件
package xin.rtime.design.decorate;// 具体组件public class ConcreteComponent implements Component {@Overridepublic String operation() {return "operation";}}
具体的装饰者
package xin.rtime.design.decorate;// 具体装饰者public class ConcreteDecorator extends Decorator {public ConcreteDecorator(Component component) {super(component);}@Overridepublic String operation() {return "ConcreteDecorator " + component.operation();}}
装饰者
package xin.rtime.design.decorate;// 装饰者public abstract class Decorator implements Component {Component component;public Decorator(Component component) {this.component = component;}}
验证
package xin.rtime.design;import java.io.BufferedOutputStream;import java.io.DataOutputStream;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import xin.rtime.design.decorate.ConcreteComponent;import xin.rtime.design.decorate.ConcreteDecorator;import xin.rtime.design.decorate.demo.PacketBodyCreator;import xin.rtime.design.decorate.demo.PacketHTMLHeaderCreator;import xin.rtime.design.decorate.demo.PacketHTTPHeaderCreator;public class DecoratorTest {@SuppressWarnings("resource")public static void main(String[] args) {// 基础装饰者模型ConcreteDecorator decorator = new ConcreteDecorator(new ConcreteComponent());System.out.println(decorator.operation());// 流的示例try {// 增加缓冲功能的流 --- 14msDataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(new File(("D:\\a.txt")))));// 没有缓存功能的流 -- 331ms//DataOutputStream dos = new DataOutputStream(// new FileOutputStream(new File(("D:\\a.txt"))));long begin = System.currentTimeMillis();for(int i=0;i<100000;i++)dos.writeLong(i);System.out.println("spend:" + (System.currentTimeMillis()-begin));} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}

