1. 程式人生 > >【Java】裝飾器模式

【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());
	}
}

執行的結果為: