目录

装饰器模式(Decorator)

装饰器模式 VS 静态代理模式


装饰器模式(Decorator)

1、动态地给一个对象增加一些额外的职责,就增加的功能来说,Decorator 模式相比生成子类更加灵活。 

2、要求装饰对象(如下所示的 Decorator)和被装饰对象(如下所示的 Source)实现同一个接口(如下所示的 Sourceable),装饰对象持有被装饰对象的实例,通过构造器传入。

3、装饰器模式的应用场景:

1)需要扩展一个类的功能。

2)动态的为一个对象增加功能,而且还能动态撤销。(继承不能做到这一点,继承的功能是静态的,不能动态增删。)

缺点:产生过多相似的对象,不易排错!多层装饰比较复杂


装饰器模型应用场景 Java java中的装饰器_装饰器模式

装饰器模式关系图

3、下面使用代码实现上图:

package main.decoratorModel;

/**
 * Created by Administrator on 2019/4/9 0009.
 * 源接口
 */
public interface Sourceable {
    //加法
    public void addition(float a, float b);

    //乘法
    public void multiplication(float a, float b);
}
package main.decoratorModel;

import java.util.logging.Logger;

/**
 * Created by Administrator on 2019/4/9 0009.
 * 计算器
 */
public class Calculator implements Sourceable {

    @Override
    public void addition(float a, float b) {
        Logger logger = Logger.getAnonymousLogger();
        logger.info(a + " + " + b + " = " + (a + b));
    }

    @Override
    public void multiplication(float a, float b) {
        Logger logger = Logger.getAnonymousLogger();
        logger.info(a + " * " + b + " = " + (a * b));
    }
}
package main.decoratorModel;

import java.util.logging.Logger;

/**
 * Created by Administrator on 2019/4/9 0009.
 * 装饰器为在不改动 Source 的基础上,为 Source 对象动态的增加新的功能
 */
public class Decorator implements Sourceable {
    private Calculator calculator;//将被装饰的对象通过参数传入

    public Decorator(Calculator calculator) {
        this.calculator = calculator;
    }

    @Override
    public void addition(float a, float b) {
        Logger logger = Logger.getAnonymousLogger();
        logger.info("操作加法前的新功能...");
        calculator.addition(a, b);
        logger.info("操作加法后的新功能...");
    }

    @Override
    public void multiplication(float a, float b) {
        Logger logger = Logger.getAnonymousLogger();
        logger.info("用户准备进行乘法运算:" + a + " * " + b);
        calculator.multiplication(a, b);
        logger.info("用户准备进行乘法运算完毕");
    }
}

4、测试如下:

package main.test;

import main.decoratorModel.Calculator;
import main.decoratorModel.Decorator;
import main.decoratorModel.Sourceable;

import java.util.logging.Logger;

/**
 * Created by Administrator on 2019/4/8 0008.
 */
public class Test {
    public static void main(String[] args) {
        Sourceable sourceable_calculator = new Calculator();
        sourceable_calculator.addition(10F, 30F);
        sourceable_calculator.multiplication(20F, 50F);

        Logger logger = Logger.getAnonymousLogger();
        logger.info("********************************************************");

        Sourceable sourceable_decorator = new Decorator(new Calculator());
        sourceable_decorator.addition(30F, 60F);
        sourceable_decorator.multiplication(25F, 30F);
    }
}

装饰器模型应用场景 Java java中的装饰器_装饰器模式_02

装饰器模式 VS 静态代理模式

1、装饰器模式与静态代理模式如果不仔细区分,则很容易混淆。区别的主要思想是:代理模式是控制控制访问,而装饰器模式是新增行为

2、相同点:

1)被装饰类与装饰类要求实现同一接口;静态代理类与目标类也要求实现同一接口
2)装饰类与静态代理类都可以实现增强目标类的功能
3)装饰类与静态代理类中都具有目标类的引用,目的都是为了在其中调用目标类的方 法

3、不同点

1)装饰器设计模式就是为了增强目标类;静态代理设计模式是为了保护和隐藏目标对象, 让客户类只能访问代理对象,而不能直接访问目标对象。
2)装饰类中的目标类的引用是通过带参构造器传入的;静态代理类中的目标类的引用, 一般都是在代理类中直接创建的,目的就是为了隐藏目标对象。
3)装饰类通常会先使用一个抽象类作为基类,基类一般不对目标对象进行增强,而是由不同的具体装饰类继承抽象装饰类后进行增强,这些具体的装饰者可以形成增强链,对目标对象进行连续增强。静态代理类会直接对目标对象进行增强,需要哪些增强的功能,一次性在静态代理类中完成,没有增强链的概念。

可以参考:http://www.runoob.com/design-pattern/decorator-pattern.html