《美化装饰:设计模式之装饰者模式》
装饰者模式
定义
先上定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式。
优缺点
优点:
1,装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用
2,通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果
3,装饰器模式完全遵守开闭原则
缺点:
装饰模式会增加许多子类,过度使用会增加程序得复杂性,维护起来比较困难
使用场景
用户在不知道内部构建细节的情况下,可以精细的控制对象的构造流程。
当需要通过对现有的一组基本功能进行排列组合而产生非常多的功能时采用继承关系很难实现,而采用装饰模式却很好实现。
解构
装饰者模式的结构和使用:
上图:
举例说明
talk is cheap,show me the code;
上代码:
现在小伙伴都喜欢喝奶茶,那么就用奶茶举个例子,奶茶有很多口味,比如红豆,椰果,我的最爱芒果等;
奶茶抽象类:
public abstract class AbstractMilkyTea {
public abstract String getContent();
public abstract double getPrice();
}
基础的奶茶类:
public class BaseMilkyTea extends AbstractMilkyTea{
@Override
public String getContent() {
return "MilkyTea";
}
@Override
public double getPrice() {
return 10.00;
}
}
抽象装饰类:
public abstract class AbstractDecorator extends AbstractMilkyTea {
private AbstractMilkyTea baseMilkyTea;
public AbstractDecorator(AbstractMilkyTea baseMilkyTea) {
this.baseMilkyTea = baseMilkyTea;
}
@Override
public String getContent() {
return baseMilkyTea.getContent();
}
@Override
public double getPrice() {
return baseMilkyTea.getPrice();
}
}
红豆奶茶类:
public class ReadBeanDecorator extends AbstractDecorator{
public ReadBeanDecorator(AbstractMilkyTea baseMilkyTea) {
super(baseMilkyTea);
}
@Override
public String getContent() {
return super.getContent()+"read bean";
}
@Override
public double getPrice() {
return super.getPrice()+2;
}
}
椰果奶茶类:
public class CoconutDecorator extends AbstractDecorator{
public CoconutDecorator(AbstractMilkyTea baseMilkyTea) {
super(baseMilkyTea);
}
@Override
public String getContent() {
return super.getContent()+"coconut";
}
@Override
public double getPrice() {
return super.getPrice()+3;
}
}
芒果奶茶类:
public class MangoDecorator extends AbstractDecorator{
public MangoDecorator(AbstractMilkyTea baseMilkyTea) {
super(baseMilkyTea);
}
@Override
public String getContent() {
return super.getContent()+"Mango";
}
@Override
public double getPrice() {
return super.getPrice()+5;
}
}
测试代码:
baseMilkyTea = new MangoDecorator(baseMilkyTea);
System.out.println(baseMilkyTea.getPrice());
System.out.println(baseMilkyTea.getContent());
Android Context举例分析
接下来我们通过Android 中的Context的类图,来了解下装饰者模式,对Android开发者应该更直观一些。
在架构设计时,应多用组合,少用继承,同时对扩展开放,对修改关闭;
上个简单的图:
Context就是抽象构件,ContextImpl作为具体构件,ContextWrapper是抽象装饰类,Service,Application就是具体装饰类;
在startActivity时候,会调用系统的handleLaunchActivity方法,接着调用performLaunchActivity方法。其中会创建一个ContextImpl. 然后activity.attach(ContextImpl)将ContextImpl赋予ContextWrapper的mBase。ContextWrapper中的所有行为全都通过mBase去实现。同时ContextWrapper通过具体的子类扩展方法不同的行为,实现对context的装饰和功能扩展。这里就不具体的展开了。