设计模式——装饰器模式

装饰器模式

动态地给对象添加一些额外的职责。就功能来说装饰模式相比生成子类更为灵活。

结构

  • 抽象组件(Component):需要装饰的抽象对象。
  • 具体组件(ConcreteComponent):是我们需要装饰的对象
  • 抽象装饰类(Decorator):内含指向抽象组件的引用及装饰者共有的方法。
  • 具体装饰类(ConcreteDecorator):被装饰的对象。
    这里写图片描述

demo

Component.class

/**
 * 组件对象的接口,可以给这些对象动态的添加职责
 * @author yuyufeng
 */
public abstract class Component {
    /**
     * 示例方法
     */
    public abstract void operation();
}

Decorator.class

/**
 * 装饰器接口,维持一个指向组件对象的接口对象, 并定义一个与组件接口一致的接口
 * 
 * @author Yu Yufeng
 *
 */
public abstract class Decorator extends Component {
    /**
     * 持有组件对象
     */
    protected Component component;

    /**
     * 构造方法,传入组件对象
     * 
     * @param component
     *            组件对象
     */
    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        // 转发请求给组件对象,可以在转发前后执行一些附加动作
        component.operation();
    }
}

ConcreteComponent.class

/**
 * 具体实现组件对象接口的对象
 * 
 * @author Yu Yufeng
 *
 */
public class ConcreteComponent extends Component {
    @Override
    public void operation() {
        // 相应的功能处理
        System.out.println("ConcreteComponent.operation()");
    }
}

ConcreteDecoratorA.class

/**
 * <p>
 * 装饰器的具体实现对象,向组件对象添加职责,operationFirst(),operationLast()为前后需要添加的功能。
 * 具体的装饰器类ConcreteDecoratorB代码相似,不在给出。
 * </p>
 * 
 * @author Yu Yufeng
 *
 */
public class ConcreteDecoratorA extends Decorator {
    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    // 在调用父类的operation方法之前需要执行的操作
    private void operationFirst() {
        System.out.println("ConcreteDecoratorA.operationFirst()");
    }

    // 在调用父类的operation方法之后需要执行的操作
    private void operationLast() {
        System.out.println("ConcreteDecoratorA.operationLast()");
    }

    // 调用父类的方法,可以在调用前后执行一些附加动作
    @Override
    public void operation() {
        operationFirst(); // 添加的功能
        super.operation(); // 这里可以选择性的调用父类的方法,如果不调用则相当于完全改写了方法,实现了新的功能
        operationLast(); // 添加的功能
    }
}

ConcreteDecoratorB.class

/**
 * <p>
 * 装饰器的具体实现对象,向组件对象添加职责,operationFirst(),operationLast()为前后需要添加的功能。
 * 具体的装饰器类ConcreteDecoratorB代码相似,不在给出。
 * </p>
 * 
 * @author Yu Yufeng
 *
 */
public class ConcreteDecoratorB extends Decorator {
    public ConcreteDecoratorB(Component component) {
        super(component);
    }

    // 在调用父类的operation方法之前需要执行的操作
    private void operationFirst() {
        System.out.println("ConcreteDecoratorB.operationFirst()");
    }

    // 在调用父类的operation方法之后需要执行的操作
    private void operationLast() {
        System.out.println("ConcreteDecoratorB.operationLast()");
    }

    // 调用父类的方法,可以在调用前后执行一些附加动作
    @Override
    public void operation() {
        operationFirst(); // 添加的功能
        super.operation(); // 这里可以选择性的调用父类的方法,如果不调用则相当于完全改写了方法,实现了新的功能
        operationLast(); // 添加的功能
    }
}

Test.class

/**
 * 装饰器模式测试
 * 
 * @author Yu Yufeng
 *
 */
public class Test {
    public static void main(String[] args) {
        Component c1 = new ConcreteComponent(); // 首先创建需要被装饰的原始对象(即要被装饰的对象)
        Decorator decoratorA = new ConcreteDecoratorA(c1); // 给对象透明的增加功能A并调用
        decoratorA.operation();

        Decorator decoratorB = new ConcreteDecoratorB(c1); // 给对象透明的增加功能B并调用
        decoratorB.operation();

        System.out.println("------------------------------------");

        // 装饰器也可以装饰具体的装饰对象,此时相当于给对象在增加A的功能基础上再添加功能B
        Decorator decoratorBandA = new ConcreteDecoratorB(decoratorA);
        decoratorBandA.operation();
    }
}

应用

java io中的 InputStream

-

示例
 File file = new File("d://test/in.txt");
  //建需要被装饰的原始对象
 InputStream inputStream = new FileInputStream(file);
 //给对象增加buffer功能
 BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream, 1024);
 byte[] bytes = new byte[10];
 int read;
 StringBuilder stringBuilder = new StringBuilder();
 while ((read = bufferedInputStream.read(bytes)) != -1) {
     stringBuilder.append(new String(bytes, 0, read));
 }
 System.out.println(stringBuilder);
组件对象的接口InputStream.class ,可以给这些对象动态的添加职责
public abstract class InputStream implements Closeable {

    public abstract int read() throws IOException;
    //...
}
装饰器接口 FilterInputStream.class ,维持一个指向组件对象的接口对象, 并定义一个与组件接口一致的接口
public
class FilterInputStream extends InputStream {

    protected volatile InputStream in;
    protected FilterInputStream(InputStream in) {
        this.in = in;
    }

    public int read() throws IOException {
        return in.read();
    }
    //...
}

猜你喜欢

转载自blog.csdn.net/qq_18860653/article/details/80481286