【Java】裝飾器模式
本文主要是介紹《【C++】裝飾器模式》(點選開啟連結)的Java版。關於什麼是裝飾器模式就不再贅述了,這次主要說明從UML類圖是如何與程式碼聯絡起來的。
還是從2012年上半年軟體設計師的軟考題來說明這個例子。
題目是這樣的:某咖啡店當賣咖啡時,可以根據顧客的要求在其中加入各種配料,咖啡店會根據所加入的配料來計算費用。咖啡店所供應的咖啡及配料的種類和價格如下表所示。
咖啡有兩種:蒸餾咖啡Espresso 25元/杯,深度烘焙咖啡DarkRoast 20元/杯
可以在咖啡裡面加配料:摩卡Mocha 10元/份,奶泡Whip 8元/份
現採用裝飾器模式Decorator模式來實現計算費用的功能,得到如圖5-1所示的類圖。
1、UML中,白色箭頭代表繼承關係,例如上圖Espresso就繼承了Beverage,從上述的UML可以看到,Beverage是所有類的父類,然而題目在Beverage類中定義了類成員,也出先有程式碼體的getDescription(),因此註定Beverage只可能是抽象類abstract而不是介面。而int cost()方法不想在此類給出相應的實現,因此必須定義為抽象方法。
2、CondimentDecorator的分析從下面已經給出的Mocha與Whip入手,因為其子類Mocha與Whip的構造方法出現了CondimentDecorator的父類——Beverage中沒有的Beverage beverage,因此其CondimentDecorator必須有一個Beverage beverage;定義,而Beverage中存在的方法與宣告,就無須再寫了。
3、最後,本題詢問主函式的建構函式是如何的。沒什麼好說的,就是根據類中定義的方法,傳入正確的引數。
就可以達到了最終的層層疊加的裝飾器模式目的。
具體實現程式碼如下所示:
abstract class Beverage { // 飲料 String description = "Unknown Beverage"; public String getDescription() { return description; } public abstract int cost(); } abstract class CondimentDecorator extends Beverage { // 配料 Beverage beverage; } class Espresso extends Beverage { // 蒸餾咖啡 private final int ESPRESSO_PRICE = 25; public Espresso() { description = "Espresso"; } public int cost() { return ESPRESSO_PRICE; } } class DarkRoast extends Beverage { // 深度烘焙咖啡 private final int DARKROAST_PRICE = 20; public DarkRoast() { description = "DarkRoast"; } public int cost() { return DARKROAST_PRICE; } } class Mocha extends CondimentDecorator { // 摩卡 private final int MOCHA_PRICE = 10; public Mocha(Beverage beverage) { this.beverage = beverage; } public String getDescription() { return beverage.getDescription() + ", Mocha"; } public int cost() { return MOCHA_PRICE + beverage.cost(); } } class Whip extends CondimentDecorator { // 奶泡 private final int WHIP_PRICE = 8; public Whip(Beverage beverage) { this.beverage = beverage; } public String getDescription() { return beverage.getDescription() + ", Whip"; } public int cost() { return WHIP_PRICE + beverage.cost(); } } public class Coffee { public static void main(String args[]) { Beverage beverage = new DarkRoast(); beverage = new Mocha(beverage); beverage = new Whip(beverage); System.out.println(beverage.getDescription() + "¥" + beverage.cost()); } }
執行的結果為: