装饰者模式
装饰者模式以对客户端透明的方式扩展原有对象的功能,不通过继承的方式,比使用子类更加灵活,原有子类结构也无需改变,不影响子类。
使用场景,及优缺点
使用场景:
替代继承,扩展一个类的功能
动态的给一个对象添加功能,以及动态的撤销该功能
优点
动态扩展一个实现类的功能,在不需要添加功能的时候,可以撤销装饰。
装饰类和被装饰类模块间,通过抽象产生依赖,不会相互耦合
装饰模式替换继承,可以避免继承链的子类被影响
- Component 抽象组件对象。Component一般是一个接口或者抽象类,定义最原始、最基本的对象。
- ConcreteComponent 具体对象。实现Component,被装饰器装饰的原始对象。
- Decorator 所有装饰类的父类。实现Component,并持有一个Component对象。
- ConcreteDecorator 装饰类,实现具体的装饰功能。
接口、具体构建类
package com.ccz.demo.design.decorated; /** * 装饰者 * 抽象构件 */ public interface Component { public void move(); }
/** * 具体构建 */ public class ConcreteComponent implements Component{ @Override public void move() { System.out.println("ConcreteComponent move ... ..."); } }
package com.ccz.demo.design.decorated; /** * 装饰(Decorator)角色 */ public class Decorator implements Component{ private Component component; public Decorator(Component component) { this.component = component; } // 委派给构件 @Override public void move() { component.move(); } }
package com.ccz.demo.design.decorated; /** * 具体装饰角色A */ public class ConcreteDecoratorA extends Decorator { public ConcreteDecoratorA(Component component) { super(component); } @Override public void move() { System.out.println("ConcreteDecoratorA business ........"); } }
package com.ccz.demo.design.decorated; /** * 具体装饰角色B */ public class ConcreteDecoratorB extends Decorator { public ConcreteDecoratorB(Component component) { super(component); } @Override public void move() { System.out.println("ConcreteDecoratorB business ........"); } }
package com.ccz.demo.design.decorated; public class DecoratedClient { public static void main(String[] args) { Component component = new ConcreteComponent(); component.move(); Component decoratorA = new ConcreteDecoratorA(component); decoratorA.move(); Component decoratorB = new ConcreteDecoratorA(component); decoratorB.move(); } }
装饰模式的应用场景及案例
- 需要扩展一个类的功能,或给一个类增加附加功能。
- 需要动态地给一个对象增加功能,这些功能可以再动态地撤销。
- Java中I/O流就是装饰模式最典型的应用。
OutputStream 是最原始的抽象组件对象,
FileOutputStream 是被装饰类,
FilterOutputStream 是装饰类的父类
BufferedOutputStream 和 DataOutputStream 是装饰类。