装饰器模式

什么是装饰器模式

  装饰器模式又称包装(Wrapper)模式,可以实现动态的为对象添加功能。是继承关系的一个替代方案,由于能够在不创造子类的状况下将对象的功能加以扩展。html

  一般给对象添加新功能,要么直接修改对象添加,要么派生对应的子类添加或者使用对象组合的方式。在面上对象的设计中,咱们应该尽可能使用对象组合而不是对象继承来扩展。装饰器模式就是基于对象组合的方式,能够很灵活的给对象添加所须要的功能。java

装饰器模式的结构和说明

  -抽象构件角色(Component):给出一个抽象接口,以规范准备接收附加责任对象。git

  -具体构件角色(Concrete Component):定义一个将要接收附加责任的类。app

  -装饰角色(Decorator):持有一个构件(Component)对象引用,并定义一个与抽象构件接口一致的接口ide

  -具体装饰角色(Concrete Decorator):负责给构件对象“贴上”附加的责任测试

                              

装饰器模式的特色

  -装饰器对象和真是对象有相同的接口。这样客户端对象就能够和真实对象相同的方式和装饰对象交互。this

  -装饰对象包含一个真实对象的引用。spa

  -装饰对象接收全部来自客户端的请求。它把这些请求转发给真实的对象。.net

  装饰对象能够在转发这些请求之前或之后增长一些附加功能。这样就确保了在运行时,不能修改给定对象的构件就能够在外部增长附加功能。在面向对象的设计中,一般是经过集成来实现对给定类的功能扩展设计

 

示例:

  步骤:

  1. 写一个组件对象接口 Component.java
  2. 写一个类 ConcreteComponent.java 实现 组件对象接口
  3. 写一个装饰器抽象类 Decorator.java 实现组件接口
  4. 写装饰器具体的实现对象 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

相关文章
相关标签/搜索