设计模式之装饰者模式
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
装饰者模式
定义
先上定义指在不改变现有对象结构的情况下动态地给该对象增加一些职责即增加其额外功能的模式。
优缺点
优点
1装饰器是继承的有力补充比继承灵活在不改变原有对象的情况下动态的给一个对象扩展功能即插即用
2通过使用不用装饰类及这些装饰类的排列组合可以实现不同效果
3装饰器模式完全遵守开闭原则
缺点
装饰模式会增加许多子类过度使用会增加程序得复杂性维护起来比较困难
使用场景
用户在不知道内部构建细节的情况下可以精细的控制对象的构造流程。
当需要通过对现有的一组基本功能进行排列组合而产生非常多的功能时采用继承关系很难实现而采用装饰模式却很好实现。
解构
装饰者模式的结构和使用
- 抽象构件Component角色它是具体构件和抽象装饰类的共同父类声明了在具体构件中实现的业务方法它的引入可以使客户端以一致的方式处理未被装饰的对象以及装饰之后的对象实现客户端的透明操作。
- 具体构件ContextImpl角色它是抽象构件类的子类用于定义具体的构件对象实现了在抽象构件中声明的方法装饰器可以给它增加额外的职责方法。
- 抽象装饰Decorator角色它也是抽象构件类的子类抽象装饰类不一定是抽象方法。用于给具体构件增加职责但是具体职责在其子类中实现。它维护一个指向抽象构件对象的引用通过该引用可以调用装饰之前构件对象的方法并通过其子类扩展该方法以达到装饰的目的。
- 具体装饰ConcreteDecorator角色它是抽象装饰类的子类负责向构件添加新的职责。每一个具体装饰类都定义了一些新的行为它可以调用在抽象装饰类中定义的方法并可以增加新的方法用以扩充对象的行为。
上图
举例说明
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的装饰和功能扩展。这里就不具体的展开了。