Decorator模式
- 动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活。装饰模式是一种对象结构型模式。装饰模式是一种用于替代继承的技术,使用对象之间的关联关系取代类之间的继承关系。在装饰模式中引入了装饰类,在装饰类中既可以调用待装饰的原有类的方法,还可以增加新的方法,以扩充原有类的功能。
- 适用场景:装饰原有对象、在不改变原有对象的情况下扩展增强新功能/新特征.。当不能采用继承的方式对系统进行扩展或者采用继承不利于系统扩展和维护时可以使用装饰模式。
实现步骤
- 看需要被增强的对象继承了哪些类或者接口,编写一个类去继承或者实现这些接口或者父类
- 在这个编写的类中,增加一个变量,变量类型为要增强的对象的类型;然后定义构造函数,构造这个变量;
- 这个类去实现接口或者父类时,调用2中定义的变量的相应方法(从而在装饰类中保留原有类的方法)
- 重写需要增强的方法(从而增强要装饰的方法,增强这个方法的功能)
举例
- 装饰模式中的四种角色
- ①Component(抽象构件):它是具体构件和抽象装饰类的共同父类,声明了在具体构件中实现的业务方法。
- ②ConcreteComponent(具体构件):它是抽象构件类的子类,用于定义具体的构件对象(被装饰者),实现了在抽象构件中声明的方法,装饰器可以给它增加额外的职责(方法)。
- ③Decorator(抽象装饰类):它也是抽象构件类的子类,用于给具体构件增加职责,但是具体职责在其子类中实现。它维护一个指向抽象构件对象的引用,通过该引用可以调用装饰之前构件对象的方法,并通过其子类扩展该方法,以达到装饰的目的。
- ④ConcreteDecorator(具体装饰类):它是抽象装饰类的子类,负责向构件添加新的职责。每一个具体装饰类都定义了一些新的行为,它可以调用在抽象装饰类中定义的方法,并可以增加新的方法用以扩充对象的行为。
- 抽象构件 Component.Java
[code lang=java] package decorator; /** * Created by liuhang on 2016/12/15. * 角色:抽象构件 Component.Java */ public abstract class Component { public abstract void operation(); } [/code]
- 具体构件类 ConcreteComponent.java
[code lang=java] package decorator; /** * Created by liuhang on 2016/12/15. * 具体构建类,继承抽象类Component */ public class ConcreteComponent extends Component{ @Override public void operation() { System.out.println("我是具体的构件类,被装饰(增强)的"); } } [/code]
[code lang=java] package decorator; /** * Created by liuhang on 2016/12/15. * 作用:引入抽象构件类, 给具体构件类增加职责,但是具体职责在其子类中实现 */ public class Decorator extends Component { private Component component; public Decorator(Component component) { this.component = component; } @Override public void operation() { //调用原有业务方法 component.operation(); } } [/code]
[code lang=java] package decorator; /** * Created by liuhang on 2016/12/15. */ public class ConcreteDecoratorA extends Decorator { public ConcreteDecoratorA(Component component) { super(component); } @Override public void operation() { super.operation(); addedBehavior(); } private void addedBehavior(){ System.out.println("我是具体的装饰类A,我可以增强原有对象方法"); } } [/code]
[code lang=java] package decorator; /** * Created by liuhang on 2016/12/15. */ public class ConcreteDecoratorB extends Decorator { public ConcreteDecoratorB(Component component) { super(component); } @Override public void operation() { super.operation(); addedAnotherBehavior(); } private void addedAnotherBehavior(){ System.out.println("我是具体的装饰类B,我也可以增强原有对象方法"); } } [/code]
[code lang=java] package decorator; /** * Created by liuhang on 2016/12/15. */ public class Test { public static void main(String[] args) { Component component, decoratorA; component = new ConcreteComponent(); decoratorA = new ConcreteDecoratorA(component);//对原有具体构件component进行装饰 component.operation(); System.out.println("\n装饰一次后:"); decoratorA.operation(); System.out.println("\n二次装饰"); Component decoratorB; decoratorB = new ConcreteDecoratorB(decoratorA);// 如果需要对原有构件对象装饰后的decoratorA对象上进行再次装饰 decoratorB.operation(); } } [/code]
[code lang=shell] 我是具体的构件类,被装饰(增强)的 装饰一次后: 我是具体的构件类,被装饰(增强)的 我是具体的装饰类A,我可以增强原有对象方法 二次装饰 我是具体的构件类,被装饰(增强)的 我是具体的装饰类A,我可以增强原有对象方法 我是具体的装饰类B,我可以增强原有对象方法 Process finished with exit code 0 [/code]
参考