什么是装饰器模式
装饰器模式又称包装(Wrapper)模式,能够实现动态的为对象添加功能。是继承关系的一个替代方案,因为可以在不创造子类的情况下将对象的功能加以扩展。
通常给对象添加新功能,要么直接修改对象添加,要么派生对应的子类添加或者使用对象组合的方式。在面上对象的设计中,我们应该尽量使用对象组合而不是对象继承来扩展。装饰器模式就是基于对象组合的方式,可以很灵活的给对象添加所需要的功能。
装饰器模式的结构和说明
-抽象构件角色(Component):给出一个抽象接口,以规范准备接收附加责任对象。
-具体构件角色(Concrete Component):定义一个将要接收附加责任的类。
-装饰角色(Decorator):持有一个构件(Component)对象引用,并定义一个与抽象构件接口一致的接口
-具体装饰角色(Concrete Decorator):负责给构件对象“贴上”附加的责任
装饰器模式的特点
-装饰器对象和真是对象有相同的接口。这样客户端对象就可以和真实对象相同的方式和装饰对象交互。
-装饰对象包含一个真实对象的引用。
-装饰对象接收所有来自客户端的请求。它把这些请求转发给真实的对象。
装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不能修改给定对象的构件就可以在外部增加附加功能。在面向对象的设计中,通常是通过集成来实现对给定类的功能扩展
示例:
步骤:
- 写一个组件对象接口 Component.java
- 写一个类 ConcreteComponent.java 实现 组件对象接口
- 写一个装饰器抽象类 Decorator.java 实现组件接口
- 写装饰器具体的实现对象 ConcreteDecorator1.java和ConcreteDecorator2.java
步骤一:写一个组件对象接口
package org.burning.sport.design.pattern.decoratorpattern; /** * @Description: 组件对象接口,可以给这些对象动态的添加职责 */ public interface Component { public void doSomething(); }
步骤二:写一个具体构件角色
package org.burning.sport.design.pattern.decoratorpattern; /** * @Description: 具体的组件对象,实现了组件接口。该对象通常就是被装饰器装饰的原始对象,可以给这个对象添加职责 */ public class ConcreteComponent implements Component { @Override public void doSomething() { System.out.println("功能A"); } }
步骤三:写一个装饰器抽象类
package org.burning.sport.design.pattern.decoratorpattern; /** * @Description: 所有装饰器的父类,需要定义一个与组件接口一致的接口(主要是为了实现装饰器功能的复用, * 即具体的装饰器A可以装饰另外一个具体的装饰器B,因为装饰器类也是一个Component),并持有一个Component对象, * 该对象其实就是被装饰的对象。如果不实现组件接口类,则只能为某个组件添加单一的功能, * 即装饰器对象不能再装饰其他的装饰器对象 */ public abstract class Decorator implements Component { /** * 持有组件对象 */ private Component component; public Decorator(Component component) { this.component = component; } @Override public void doSomething() { //转发请求给组件对象,可以在转发前后执行一些附加动作 component.doSomething(); } }
步骤四:写装饰器具体的实现对象
package org.burning.sport.design.pattern.decoratorpattern; /** * @Description: 具体的装饰器类,实现具体要向被装饰对象添加的功能。用来装饰具体的组件对象或者另外一个具体的装饰器对象 */ public class ConcreteDecorator1 extends Decorator { public ConcreteDecorator1(Component component) { super(component); } @Override public void doSomething() { super.doSomething(); this.doAnotherThing(); } /** * 新功能 */ private void doAnotherThing() { System.out.println("功能B"); } }
package org.burning.sport.design.pattern.decoratorpattern; /** * @Description: 具体的装饰器类,实现具体要向被装饰对象添加的功能。用来装饰具体的组件对象或者另外一个具体的装饰器对象 */ public class ConcreteDecorator2 extends Decorator{ public ConcreteDecorator2(Component component) { super(component); } @Override public void doSomething() { super.doSomething(); this.doAnotherThing(); } private void doAnotherThing() { System.out.println("功能C"); } }
步骤五:测试
package org.burning.sport.design.pattern.decoratorpattern; /** * @Description: 装饰器模式(包装模式Wrapper) * 装饰模式能够实现动态的为对象添加功能,是从一个对象外部来给对象添加功能。 * 装饰器模式的本质就是动态组合,动态是手段,组合才是目的 */ public class ClientMain { public static void main(String[] args) { //节点流 // Component component = new ConcreteComponent(); //首先创建需要被装饰的原始对象(即要被装饰的对象) //过滤流 // Component component2 = new ConcreteDecorator1(component); //给对象透明的增加功能B并调用 //过滤流 // Component component3 = new ConcreteDecorator2(component2);//给对象透明的增加功能C并调用 // component3.doSomething(); Component component1 = new ConcreteDecorator1(new ConcreteDecorator2(new ConcreteComponent())); component1.doSomething(); } }
https://gitee.com/play-happy/base-project
参考:
[1] 博客, http://blog.csdn.net/hust_is_lcd/article/details/7884320
[2] 博客,http://www.runoob.com/design-pattern/decorator-pattern.html