通常为了给一个类增加行为,我们会使用继承机制,但是继承机制是静态的,用户不能控制增加行为的方式和时机。而在装饰模式这一设计模式中,我们可以动态的给一个对象增加一些额外的功能,比继承更有灵活性,利于扩展,满足设计模式中的一个重要原则,对修改关闭(避免引入bug)对扩展开放(程序具有弹性)。装饰模式包括如下角色,Component抽象构建,ConcreteComponent具体构建,Decorator抽象装饰类,ConcreteDecorator具体装饰类,这几个角色的类图关系如下
拿咖啡来举例
咖啡店会提供很多种咖啡,比如HouseBlend,DarkRoast,Espresso,Decaf四种咖啡类型,而调料有Milk,Mocha,Soy,Whip四种调料,如果使用继承的方式那么会有HouseBlendWithMilk,HouseWithMocha,HouseWithSoy,HouseWithWhip,DarkWithMilk…等12个类。而且这还不包括HouseBlendWith2Milk,也就是说调料加倍的情况
装饰模式可以比较好的解决这个问题
装饰模式演示如下演示
抽象类构建也就是基本的饮料类
public abstract class Beverage {
protected String description = "Unknown Beverage";
public String getDescription() {
return description;
}
public abstract int cost();
}
DarkRoast类继承Beverage并给出具体的价格
public class DarkRoast extends Beverage {
public DarkRoast() {
description = "darkroast";
}
@Override
public int cost() {
return 90;
}
}
public class Espresso extends Beverage {
public Espresso() {
description = "Espresso";
}
@Override
public int cost() {
return 85;
}
}
public class HouseBlend extends Beverage {
public HouseBlend() {
description = "House Blend Coffee";
}
@Override
public int cost() {
return 20;
}
}
抽象装饰类继承抽象构建
public abstract class CondimentDecorator extends Beverage {
}
Mocha调料
public class Mocha extends CondimentDecorator {
private Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ",Mocha";
}
@Override
public int cost() {
return beverage.cost() + 30;
}
}
public class Soy extends CondimentDecorator {
private Beverage beverage;
public Soy(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+",soy";
}
@Override
public int cost() {
return beverage.cost() + 25;
}
}
public class Whip extends CondimentDecorator {
private Beverage beverage;
public Whip(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ",whip";
}
@Override
public int cost() {
return beverage.cost() + 56;
}
}
演示
public class CoffeeTest {
public static void main(String[] args) {
Beverage beverage = new Espresso();
System.out.println("description -> " + beverage.getDescription() + ",cost -> " + beverage.cost());
Beverage beverage1 = new DarkRoast();
beverage1 = new Mocha(beverage1);
beverage1 = new Mocha(beverage1);
beverage1 = new Whip(beverage1);
System.out.println("description -> " + beverage1.getDescription() + ",cost -> " + beverage1.cost());
}
}