设计模式之装饰模式

/ 移动技术Java / 没有评论 / 273浏览

前言

为什么要写装饰模式?这几天在工作中又遇到了RePlugin。在RePlugin中有插件和宿主的概念,插件和宿主分别有自己的Context。通过以下两个方法可以分别获得宿主和插件的Context。

RePlugin是一套完整的、稳定的、适合全面使用的,占坑类插件化方案,由360手机卫士的RePlugin Team研发,也是业内首个提出"全面插件化"(全面特性、全面兼容、全面使用)的方案。

RePlugin.getHostContext();
RePlugin.getPluginContext();        

于是笔者读了以上两个方法的源码,进而读了一下Context类的部分源码和继承关系。看到有关Context类中使用了装饰模式。故而打算写一篇介绍装饰模式的文章,下一篇文章会再介绍Context的继承结构,以及在RePlugin中两个Context是如何得到的。

什么是装饰模式

装饰模式(Decorator Pattern)又叫包装模式,它是结构型模式的一种。装饰模式可以动态的给对象添加一些额外的职责,它比继承更加灵活。如何理解这种灵活性?笔者认为通过继承的方式添加一些功能,必然要改动子类。但是使用装饰模式,可以通过新增一个装饰类而不必修改之前的代码。

装饰模式的结构图

1.png

装饰模式包含如下角色:

装饰模式实现

下面按照装饰模式的结构图来实现一下装饰模式

1. 定义抽象组件 Component
public abstract class Component {
    public abstract void operation();
}
2. 定义具体组件(被装饰者) ConcreteComponent
public class ConcreteComponent extends Component {

    @Override
    public void operation() {

        System.out.println("被装饰对象");
    }

}
3. 定义抽象装饰类 Decorator
public abstract class Decorator extends Component {

    protected Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        if (component != null) {
            component.operation();
        }
    }
}

4. 定义具体装饰类,这里定义两个ConcreteDecoratorA和ConcreteDecoratorB
public class ConcreteDecoratorA extends Decorator {

    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        super.operation();

        addDecoratorA("A");
    }

    private void addDecoratorA(String decorator) {
        System.out.println("给对象装饰" + decorator);
    }
}

public class ConcreteDecoratorB extends Decorator {

    public ConcreteDecoratorB(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        super.operation();

        addDecoratorB("B");
    }

    private void addDecoratorB(String decorator) {
        System.out.println("给对象装饰" + decorator);
    }
}

这样装饰模式的实现就完成了,接下来调用一下。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        ConcreteComponent component = new ConcreteComponent();

        ConcreteDecoratorA decoratorA = new ConcreteDecoratorA(component);

        ConcreteDecoratorB decoratorB = new ConcreteDecoratorB(component);

        decoratorA.operation();

        decoratorB.operation();
    }
}

打印输出结果:

I/System.out: 被装饰对象
I/System.out: 给对象装饰A
I/System.out: 被装饰对象
I/System.out: 给对象装饰B

可以看到ConcreteComponent此时已经具有了A和B的功能,同时ConcreteComponent 并不知道ConcreteDecoratorAConcreteDecoratorB 的存在。当我们要给ConcreteComponent增加其他功能,可以在不改变原有代码的前提下,动态的扩展ConcreteComponent的功能,只需要给ConcreteComponent增加新的装饰类即可。当然装饰模式也有一个小小的缺点,就是它会增加代码的复杂性。可根据实际情况选择是否使用装饰模式。

demo地址:https://github.com/77Y/Decorator