装饰者模式:
OO原则:
封装变化
多用组合,少用继承
针对接口编程,不针对实现编程
为交互对象之间的松耦合设计而努力
对扩展开放,对修改关闭
问题来源:
在购买咖啡时,可以要求在其中加入各种调料,例如:蒸奶,豆浆,摩卡等其他调料,会根据加入的不同调料而收取不同的费用。
第一个尝试:
发现问题所在:
1,调料价钱的改变会使我们更改现有代码
2,一旦出现新的调料我们就要加入新的方法,并改变超类中的cost()方法
3,以后可能会开发出新饮料,对这些饮料而言,某些调料可能并不适合,但是在这种设计方案中,子类仍将继承那些不合适的方法
4,顾客如果要双倍的摩卡怎么办
装饰者模式山药出场啦!!!
先看设计图:
代码实现:
两个基类,一个咖啡,一个调料
1
public abstract class Beverage {
String description = "Unkown Beverage";
public String getDescription(){
return description;
}
public abstract double cost();
}
2
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
咖啡的具体实现:
1
public class Espresso extends Beverage{
public Espresso(){
description = "Espresso";
}
@Override
public double cost() {
return 1.99;
}
}
2
public class HouseBlend extends Beverage{
public HouseBlend(){
description = "HouseBlend";
}
public double cost() {
return .89;
}
}
调料的具体实现:
1
public class Mocha extends CondimentDecorator{
Beverage beverage;
public Mocha(Beverage beverage){
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", Mocha";
}
public double cost() {
return .20+beverage.cost();
}
}
2
public class Soy extends CondimentDecorator{
Beverage beverage;
public Soy(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+", Soy";
}
@Override
public double cost() {
return .10 + beverage.cost();
}
}
最后测试代码:
public class StarbuzzCoffee {
public static void main(String[] args) {
Beverage beverage = new Espresso();
// System.out.println(beverage.getDescription() + " $" + beverage.cost());
beverage = new Mocha(beverage);
beverage = new Soy(beverage);
beverage = new Mocha(beverage);
// beverage = new Mocha(beverage);
System.out.println(beverage.getDescription() + " $" + beverage.cost());
}
}