装饰模式
装饰模式(Decorator Pattern)是一种比较常见的模式,动态地给一个对象添加一些额外的职责。不改变原有对象动态扩展,可替代继承但是多层装饰会导致复杂化。
假设我们现在有个奶茶店,我们制作奶茶,假如客户需要加红豆、椰果则需要加钱。我们可以理解为是将奶茶进行扩展。
例如Mybatis中切换二三级缓存的时候就用的装饰模式,像spring配置多数据源有不同的数据库连接也可以使用装饰模式。
1、创建奶茶接口,里面有奶茶制作与对应金额方法
package com.mode.decorator;
public interface Milk {
public void createMilk();
public int priceMilk();
}
2、实现奶茶接口,一个是柠檬奶茶是17元,一个是芒果奶茶是22元。
package com.mode.decorator;
/**
* 柠檬奶茶制作
*/
public class LemonMilk implements Milk{
@Override
public void createMilk() {
System.out.println("制作了一杯柠檬奶茶");
}
@Override
public int priceMilk() {
return 17;
}
}
package com.mode.decorator;
/**
* 芒果奶茶制作
*/
public class MangoMilk implements Milk{
@Override
public void createMilk() {
System.out.println("制作了一杯芒果奶茶");
}
@Override
public int priceMilk() {
return 22;
}
}
3、创建我们的装饰类,通过有参构造传参来调用奶茶接口
package com.mode.decorator;
/**
* 装饰奶茶类
*/
public abstract class MilkDecorator implements Milk{
public Milk milk;
public MilkDecorator(Milk milk){
this.milk=milk;
}
@Override
public void createMilk() {
this.milk.createMilk();
}
@Override
public int priceMilk() {
return this.milk.priceMilk();
}
}
4、现在我们对奶茶进行扩展,继承我们的奶茶装饰类。
package com.mode.decorator;
public class ExtMilkDecorator extends MilkDecorator{
public int yeguoPrice = 3;
public ExtMilkDecorator(Milk milk) {
super(milk);
}
public void createMilk() {
super.createMilk();
this.extMilk();
}
public void extMilk(){
System.out.println("加一份椰果");
}
public int priceMilk() {
return super.priceMilk()+yeguoPrice;
}
}
5、测试接口
package com.mode.decorator;
public class TestDecorator {
public static void main(String[] args) {
ExtMilkDecorator extMilkDecorator = new ExtMilkDecorator(new LemonMilk());
extMilkDecorator.createMilk();
int price = extMilkDecorator.priceMilk();
System.out.println("柠檬奶茶价格" + price);
System.out.println("----------------------------");
ExtMilkDecorator extMilkDecorator2 = new ExtMilkDecorator(new MangoMilk());
extMilkDecorator2.createMilk();
int price2 = extMilkDecorator2.priceMilk();
System.out.println("芒果奶茶价格" + price2);
}
}
6、结果—>可以得出奶茶加了椰果后的价格