前言
为什么要写装饰模式?这几天在工作中又遇到了RePlugin。在RePlugin中有插件和宿主的概念,插件和宿主分别有自己的Context。通过以下两个方法可以分别获得宿主和插件的Context。
RePlugin是一套完整的、稳定的、适合全面使用的,占坑类插件化方案,由360手机卫士的RePlugin Team研发,也是业内首个提出"全面插件化"(全面特性、全面兼容、全面使用)的方案。
RePlugin.getHostContext();
RePlugin.getPluginContext();
于是笔者读了以上两个方法的源码,进而读了一下Context类的部分源码和继承关系。看到有关Context类中使用了装饰模式。故而打算写一篇介绍装饰模式的文章,下一篇文章会再介绍Context的继承结构,以及在RePlugin中两个Context是如何得到的。
什么是装饰模式
装饰模式(Decorator Pattern)又叫包装模式,它是结构型模式的一种。装饰模式可以动态的给对象添加一些额外的职责,它比继承更加灵活。如何理解这种灵活性?笔者认为通过继承的方式添加一些功能,必然要改动子类。但是使用装饰模式,可以通过新增一个装饰类而不必修改之前的代码。
装饰模式的结构图
装饰模式包含如下角色:
- Component: 抽象组件。定义一个抽象类或接口。
- ConcreteComponent: 具体组件。即被装饰者,给这个类的对象添加一些职责。
- Decorator: 抽象装饰类。
- ConcreteDecorator: 具体装饰类。给组件添加职责。
装饰模式实现
下面按照装饰模式的结构图来实现一下装饰模式
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 并不知道ConcreteDecoratorA 和 ConcreteDecoratorB 的存在。当我们要给ConcreteComponent增加其他功能,可以在不改变原有代码的前提下,动态的扩展ConcreteComponent的功能,只需要给ConcreteComponent增加新的装饰类即可。当然装饰模式也有一个小小的缺点,就是它会增加代码的复杂性。可根据实际情况选择是否使用装饰模式。
demo地址: github.com/77Y/Decorat…