装饰模式
装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
小洪的故事
出场人物:小洪、老黑
话说这天,湖人落后灰熊11分,小洪与老黑打赌,如果湖人能赢就请老黑喝奶茶!万万没想到的是,话音刚落不久,湖人打出一波12:0的冲击波反超1分。小洪为他的年少气盛付出了一杯奶茶的代价。
“学校外面有条街,那里的益禾堂不错,待会就去喝这个了。”还没放学老黑就已经在盘算着怎么利用好这次机会坑小洪了。
“行咯。”小洪向来愿赌服输。
放学后他们直奔益禾堂而来,因为再慢一步这里就要排满人了。
装饰模式初体验
”哇,珍珠红茶、芒果红茶、烤珍珠芒果红茶,这里好多种类啊,但不知道哪一种比较好吃。“老黑上下观望着点单,选择困难症的毛病又犯了。
“老黑啊,你只看到了表面,没有看到本质啊。”
“什么本质?”
“你看,虽然这里种类繁多且花里胡哨,但其实本质他们都是红茶、绿茶等,外加一些调料进行装饰而已。”
“你这么说也有道理哦。”
“这种设计模式就是刚才老师上课讲到的装饰模式了。”
从图中可以看到:绿茶、红茶作为接口奶茶的实现类,如果我们想要增强或是修饰这两个实现类,就采用装饰模式,而珍珠、芒果等都是奶茶的装饰类,以达到修饰的目的。虽然样式很多,但其实原料也没几样,但是可以搭配出很多组合。
奶茶类
public abstract class Drink {
// 奶茶信息
public abstract String desc();
// 花费的价钱
public abstract int cost();
}
public class GreenTea extends Drink {
@Override
public String desc() {
return "绿茶";
}
@Override
public int cost() {
return 7;
}
}
public class BlackTea extends Drink {
@Override
public String desc() {
return "红茶";
}
@Override
public int cost() {
return 6;
}
}
装饰类
public abstract class Condiment extends Drink {
}
public class Lemon extends Condiment {
private Drink drink;
public Lemon(Drink drink) {
this.drink = drink;
}
@Override
public String desc() {
return drink.desc() + "加柠檬";
}
@Override
public int cost() {
return drink.cost() + 3;
}
}
public class Mango extends Condiment {
private Drink drink;
public Mango(Drink drink){
this.drink = drink;
}
@Override
public String desc() {
return drink.desc() + "加芒果";
}
@Override
public int cost() {
return drink.cost() + 4;
}
}
客户端进行调用
public class People {
public static void main(String[] args) {
Drink drink = new GreenTea();
drink = new Lemon(drink);
drink = new Mango(drink);
System.out.println(drink.desc());
System.out.println(drink.cost());
}
}
运行结果
绿茶加柠檬加芒果
花费14元
“怎么样,懂了吧,可把你上课没听的内容给补回来了。”没想到小洪也有能教别人的一天。
“懂了懂了,原来点奶茶是可以不看名字自己加调料的。”老黑点点头,转头就对老板说道,
“老板,我要一杯绿茶,加芒果、布丁、珍珠、椰果、红豆、还有那啥,都给我加上去,大杯!”
一旁的小洪目瞪口呆,“早知道我就不教他了,还赔上我两倍奶茶钱。”