装饰设计模式也是我们常用到的设计模式,可以动态地将职责附加到对象上。若要拓展功能,装饰者提供了比继承更有弹性的替代方案
下面我们来看一个例子:
假如我们现在有一个咖啡店,里面有多种饮料,饮料里面还可以添加多种配料,于是我们使用了装饰者模式,用配料来装饰饮料;
例如,我们要一杯摩卡饮料,或则一杯奶茶豆浆饮料,饮料(Baverage)是被修饰的,摩卡和豆浆,奶茶(Decor)都是修饰者。
//饮料抽象类 public abstract class Baverage { protected String description; public Baverage() { description = "Not Baverage"; } public String getDescription() { return description; } abstract float getCost(); }
//装饰者的抽象类,所有装饰者都必须重写这个方法 public abstract class CordimentDecor extends Baverage{ public abstract String getDescription();//每个装饰者必须重写这个方法,下面会重新提到 }上面这两个类分别是被装饰者和装饰者的抽象类,装饰者的抽象类要继承Baverage是为了实现类型匹配,而装饰的功能是来自于装饰者和组件组合时,由组合对象获得的
//具体组件 public class HouseBlend extends Baverage { public HouseBlend() { description = "HouseBlend";//这里的实例description是继承Baverage得来的 } @Override float getCost() { return (float) 1.9; } }
//具体装饰者 public class MochaDecor extends CordimentDecor { Baverage baverager; public MochaDecor(Baverage baverager) { this.baverager = baverager; } @Override public String getDescription() { return baverager.getDescription() + ",MochaDecor";//在这里我们就可以在装饰者的基础上增加描述 } @Override float getCost() { return (float) (baverager.getCost() + 0.89);//在这里我们就可以在装饰者的基础上增加摩卡装饰物的价格了 } }
现在我们有了抽象组件,具体组件,抽象装饰物,具体装饰物,下面就可以测试下了
public class App { public static void main(String[] args) { Baverage baverage = new HouseBlend(); System.out.println(baverage.getDescription() + ", Cost = " + baverage.getCost()); baverage = new MochaDecor(baverage); baverage = new WhipDecor(baverage);// 可以包装多个装饰物 System.out.println(baverage.getDescription() + ", Cost = " + baverage.getCost()); } }输出的结果: