设计模式(四):装饰器模式
目录
装饰器模式的特点
- 为了某个实现类在不修改原始类的基础上进行动态地覆盖或者增加方法,持有原始类的引用
- 同源,该实现保持跟原有类的层级关系。
举例
首先我们定义Drink接口,包含一个taste方法,返回这个喝的味道怎么样
public interface Drink {
String taste();
}
然后用Tea,实现该接口
public class Tea implements Drink{
@Override
public String taste() {
return "茶叶水喝起来有点苦涩";
}
}
年轻人喜欢在饮料里面加点果汁,例如:茶+果汁 = 果茶,就很流行,创建果汁装饰器类(抽象装饰器),扩展Drink接口,被果汁装饰过的饮料具备了新的功能,提供维生素。
public abstract class FruitJuiceDecorator implements Drink{
public Drink drink;
public FruitJuiceDecorator(Drink drink) {
this.drink = drink;
}
@Override
public String taste() {
String oriRes = "原有的味道:"+drink.taste();
return oriRes+",装饰后的味道:"+fruitJuiceTaste();
}
public abstract void supplyVitamin();
public abstract String fruitJuiceTaste();
}
然后创建两种具体的果汁装饰器类,芒果和柠檬
public class MangoFruitJuice extends FruitJuiceDecorator {
public MangoFruitJuice(Drink drink) {
super(drink);
}
@Override
public void supplyVitamin() {
System.out.println("芒果汁可以补充维生素A");
}
@Override
public String fruitJuiceTaste() {
return "加了芒果汁变甜了";
}
}
public class LemonFruitJuice extends FruitJuiceDecorator {
public LemonFruitJuice(Drink drink) {
super(drink);
}
@Override
public void supplyVitamin() {
System.out.println("柠檬汁可以补充维生素C");
}
@Override
public String fruitJuiceTaste() {
return "加了柠檬汁变酸的";
}
@Override
public String taste() {
String res ="原来的味道:"+drink.taste();
res+=",加了柠檬汁就变算了";
return res;
}
}
最后我们就可以用柠檬汁和西瓜汁装饰原来的Tea,制作出柠檬红茶和芒果绿茶了
public class TestDecorator {
public static void main(String[] args) {
Drink tea = new Tea();
System.out.println(tea.taste());
FruitJuiceDecorator mangoTea = new MangoFruitJuice(tea);
System.out.println(mangoTea.taste());
mangoTea.supplyVitamin();
FruitJuiceDecorator lemonTea = new LemonFruitJuice(tea);
System.out.println(lemonTea.taste());
lemonTea.supplyVitamin();
}
}
装饰器的特点是同源。所有类都实现了Drink接口,装饰器覆盖了原有类的方法并或者对原有的类进行功能上的扩展,且通过对象引用而非继承来实现