目录
装饰器模式
应用场景
一点思路
装饰器模式结构视图
实例类图
解题程序代码
程序运行结果
装饰器模式
装饰器模式是为了运行时动态的扩展一个类的功能。它谨循开闭原则,它实现的关键是继承和组合的结合使用,解耦对象之间的关系。装饰器模式充分展示了组合的灵活。利用它来实现扩展。它同时也是开闭原则的体现。 如果对某个类实现运行时功能动态的扩展, 这个时候就可以考虑使用装饰器模式。
应用场景
有一个咖啡店,销售各种各样的咖啡,拿铁,卡布奇洛,蓝山咖啡等,在冲泡前,会询问顾客是否要加糖,加奶,加薄荷等。这样不同的咖啡配上不同的调料就会卖出不同的价格。采用装饰器模式实现以下要求:
(1)实现给出装饰器模式结构视图。
(2)给出该实例类图及代码实现。
一点思路
Tips:由于不同的咖啡和不同的调料得各种任意组合,使得出现类爆炸的现象。为了规避这个问题,我们可以考虑把各种调料当作属性加入到Coffee这个抽象类中,接着在实现类中计算价格和名字时,分别判断是否加入了各种调料包,得到不同的名字和价格。
稍后我们会用到开闭原则和继承和组合
开闭原则是面向对象的一个基本设计原则,即:类应该对修改关闭,对扩展开放。
假如cofee和它的一众实现拿铁,卡布奇洛,蓝山来自第三方类库,并且这个类库已经很适合且实用了。 而我们为了得到加入不同调料的咖啡的名字和价格,我们就得修改这些实现,而这样的修改,总是免不了改变稳定性。对原本的系统来说也是一种风险! 所以我们应该对修改关闭,对扩展开放。
装饰器模式结构视图
实例类图
解题程序代码
/** *@Author:XZIT_XX*/
public abstract class Coffee {
/** * 获取咖啡得名字 */
public abstract String getName();
/** * 获取咖啡的价格*/
public abstract double getPrice();
}
public abstract class Coffee {
// 是否加了牛奶
protected boolean addedMilk;
// 是否加了糖
protected boolean addedSugar;
// 是否加了薄荷
protected boolean addedMint;
/** * 获取咖啡得名字*/
public abstract String getName();
/** * 获取咖啡的价格*/
public abstract double getPrice();
}
public class BuleCoffee extends Coffee {
@Override
public String getName() {
StringBuilder name = new StringBuilder();
name.append("蓝山");
if (addedMilk) {
name.append("牛奶");
}
if (addedMilk) {
name.append("薄荷");
}
if (addedSugar) {
name.append("加糖");
}
return name.toString();
}
@Override
public double getPrice() {
double price = 10;
if (addedMilk)
price += 1.1;
if (addedMilk)
price += 3.2;
if (addedSugar)
price += 2.7;
return price;
}
}
public abstract class CoffeeDecorator implements Coffee {
private Coffee delegate;
public CoffeeDecorator(Coffee coffee) {
this.delegate = coffee;
}
@Override
public String getName() {
return delegate.getName();
}
@Override
public double getPrice() {
return delegate.getPrice();
}
}
public class MilkCoffeeDecorator extends CoffeeDecorator {
public MilkCoffeeDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getName() {
return "牛奶, " + super.getName();
}
@Override
public double getPrice() {
return 1.1 + super.getPrice();
}
}
public class App {
public static void main(String[] args) {
// 得到一杯原始的蓝山咖啡
Coffee blueCoffee = new BlueCoffee();
System.out.println(blueCoffee.getName() + ": " + blueCoffee.getPrice());
// 加入牛奶
blueCoffee = new MilkCoffeeDecorator(blueCoffee);
System.out.println(blueCoffee.getName() + ": " + blueCoffee.getPrice());
// 再加入薄荷
blueCoffee = new MintCoffeeDecorator(blueCoffee);
System.out.println(blueCoffee.getName() + ": " + blueCoffee.getPrice());
// 再加入糖
blueCoffee = new SugarCoffeeDecorator(blueCoffee);
System.out.println(blueCoffee.getName() + ": " + blueCoffee.getPrice());
}
}