装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
下面让我们来看看类图,如下:
三、装饰我们的饮料
四、写下星吧兹的代码
//Beverage是一个抽象类,有两个方法:getDescription()及cost() public abstract class Beverage{ String description = "Unknown Beverage"; //getDescription()已经在此实现了 //但是cost()必须在子类中实现 public String getDescription(){ return description; } public abstract double cost(); }
//首先,必须让CondimentDecorator能够取代Beverage //所以,将CondimentDecorator扩展自Beverage类 public abstract class CondimentDecorator extends Beverage{ //所有的调料装饰者都必须重新实现 //getDescription()方法 public abstract String getDescription(); }
现在,已经有了基类,让我们开始实现一些饮料吧!先从浓缩咖啡(Espresso)开始。
//首先让Espresso扩展自Beverage类, //因为Espresso是一种饮料 public class Espresso extends Beverage{ //为了要设置饮料的描述,我们写了一个构造器。 //description实例变量继承自Beverage public Espresso(){ description = "Esptesso"; } //最后,需要计算Expresso的价钱,现在不需要调料的价钱, //直接把Espresso的价格$1.99返回即可。 public double cost(){ return 1.99; } }
这是另外一种饮料:
public class HouseBlend extends Beverage{ public HouseBlend(){ description = "House Blend Coffee"; } public double cost(){ return .89; } }
写调料代码
如果你回头看看装饰者模式的类图,将发现我们已经完成了抽象组件(Beverage),有了
具体组件(HouseBlend),也有了抽象装饰者(CondimentDecorator)。
现在我们来实现具体装饰者。先从摩卡下手:
//摩卡是一个装饰者,所以让他扩展自Condiment。 //CondimentDecorator扩展子Beverage public class Mocha extends CondimentDecorator{ //要让Mocha能够引用一个Beverage,做法如下: //(1)用一个实例变量记录饮料,也就是被装饰者 Beverage beverage; //(2)把饮料当作构造器的参数,再由构造器将此饮料 //记录在实例变量中 public Mocha(Beverage beverage){ this.beverage = beverage; } //我们希望叙述不只是描述饮料(例如“DarkRoast”),而是完整地连调料都描述出来 //(例如:“DarkRoast,Mocha”)。所以首先利用委托的做法,得到一个叙述,然后在气候加上附加的叙述 public String getDescription(){ return beverage.getDescription()+", Mocha"; } //要就算带Mocha饮料的价钱。首先把调用委托给被装饰对象 //,以计算价钱,然后加上Mocha的价钱。得到最后结果 public double cost(){ return .20 + beverage.cost(); } }
public class StarbuzzCoffee{ public static void main(String[] args){ //订一杯Espresso,不需要调料。打印出他的描述与价钱 Beverage beverage = new Espresso(); System.out.pringln(beverage.getDescription()+" $"+beverage.cost()); //制造出一个DarkRoast对象。 Beverage beverage2 = new DarkRoast(); //用Mocha装饰他 beverage2 = new Mocha(beverage2); //用第二个Mocha装饰他 beverage2 = new Mocha(beverage2); //用Whip装饰他 beverage2 = new Whip(beverage2); System.out.pringln(beverage2.getDescription()+" $"+beverage2.cost()); //最后,再来一杯调料为豆浆、摩卡、奶泡的HouseBlend咖啡 Beverage beverage3 = new HouseBlend(); beverage3 = new Soy(beverage3); beverage3 = new Mocha(beverage3); beverage3 = new Whip(beverage3); System.out.pringln(beverage3.getDescription()+" $"+beverage3.cost()); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。