模式介绍
装饰者模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法完整性的前提下,提供了额外的功能。
模式优点
1、动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
2、装饰类和被装饰类可以独立发展,不会相互耦合,是继承的一个替代模式,可以动态扩展一个实现类的功能。
模式缺点
1、多层装饰比较复杂。
使用场景
1、扩展一个类的功能。
2、动态增加功能,动态撤销。
系统建模
1、星巴克咖啡订单项目,咖啡和调料有很多搭配。
2、创建一个饮料的接口Drink,和它的两个抽象子类Coffee、Decorator。
3、Coffee抽象类中会有两种咖啡的实现类。
4、Decorator充当装饰者,他下面会有Milk、Chocolate两种调料。
系统实现
/**
* 饮料抽象类
*/
public abstract class Drink {
public String name;
private float price = 0.0f;
public abstract float cost();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
}
/**
* 咖啡大类
*/
public class Coffee extends Drink {
@Override
public float cost() {
return super.getPrice();
}
}
/**
* 意大利咖啡
*/
public class Espresso extends Coffee{
public Espresso(){
setName("意大利咖啡");
setPrice(12.0f);
}
}
/**
* 美式咖啡
*/
public class LongBlack extends Coffee{
public LongBlack(){
setName("美式咖啡");
setPrice(15.0f);
}
}
/**
* 调味大类
*/
public class Decorator extends Drink {
private Drink drink;
public Decorator(Drink drink) {
this.drink = drink;
}
@Override
public float cost() {
return super.getPrice()+drink.cost();
}
}
/**
* 牛奶调味品
*/
public class Milk extends Decorator{
public Milk(Drink drink) {
super(drink);
setName("牛奶调味品");
setPrice(3.0f);
}
}
/**
* 巧克力调味品
*/
public class Chocolate extends Decorator {
public Chocolate(Drink drink) {
super(drink);
setName("巧克力调味品");
setPrice(3.0f);
}
}
/**
* 客户端
*/
public class Client {
public static void main(String args[]){
// 意大利咖啡
Drink espressoCoffee = new Espresso();
// 加一份牛奶
espressoCoffee = new Milk(espressoCoffee);
// 加一份巧克力
espressoCoffee = new Chocolate(espressoCoffee);
System.out.println("订单需要:"+espressoCoffee.cost()+"块钱!");
}
}
结果:
订单需要:18.0块钱!