標籤:java java設計模式 裝飾者模式
概述:
本章可以稱為“給愛用繼承的人一個全新的設計眼界”。我們即將再度探討典型濫用問題。你將在本章學到如何使用對象組合的方式,做到在運行時裝飾類。為什麼呢?一旦你熟悉了裝飾者的技巧,你將能夠在不修改任何底層代碼的情況下,給你的(或別人的)對象賦予新的職責。——《Head First 設計模式》
使用環境:
當我們有多種類型的事物,且每一種事物下面又有很多小的、細的分類。這些分類之間可以隨意組合時(例如一種飲料有一個主原料和一些配料、一道菜會有一個主原料加上一些配料或是去裝飾一個房間等等),我們就可以想一下是不是可以用裝飾模式來實現。下面就《Head First 設計模式》中的例子星巴茲的咖啡說簡單說明一下。
功能優點:
利用組合維護代碼,通過動態地組合對象,可以寫新的代碼添加新功能,而無須修改現有代碼。
思路分析:
在星巴茲的咖啡店裡,有多種咖啡,和多種調料。如果我們選擇一種咖啡另外配上一種或是幾種配料(主要主是一個被裝飾者和多個裝飾者)。那麼我們如何對這些咖啡和配料進行收費呢(這裡採用收費是一個好的舉例,當然也可以是其他的一些相同的事件)?如果你說我們對每一種可選搭配可以封裝,天呐,那該會有多少個類啊。還有一點就是,如果咖啡店裡如果有一種咖啡或是配料價格有變動,或是需要新添加一種咖啡或是配料,又該怎麼辦呢?
其實本文的模式就有一種很好的解決辦法:我們不再使用繼承,因為繼承可能會導致類爆炸的。我們試想一下,能不能把咖啡店中的的所有原料(包括主原料和所有配料)都看成是一種東西(原料)。這樣我們就可以在相互組合的過程中動態實現某些功能。可能你會問為什麼要把其看成是一種東西,這樣做的目的是為了在所有原料中實現同一功能,且無關代碼中的組合順序。
類圖展示:
當然,你也可以把上面咖啡那4個類再封一層。這裡我就書中的內容做了一個原樣輸出。
代碼展示:
Beverage.java
public abstract class Beverage {public String mDescription = "UnKnown Beverage";private int size = 0;public String getDescription() {return mDescription;}public int getSize() {return size;}public void setSize(int size) {this.size = size;}public abstract double cost();}
CondimentDecorator.java
public abstract class CondimentDecorator extends Beverage {@Overridepublic double cost() {return 0;}public abstract String getDescription();}
DarkRoast.java
public class DarkRoast extends Beverage {private double mCost = 0.99;public DarkRoast() {mDescription = "Dark Roast Coffee";}@Overridepublic double cost() {return mCost;}}
Milk.java
public class Milk extends CondimentDecorator {private Beverage mBeverage = null;private double mCost = 0.10;public Milk(Beverage beverage) {mBeverage = beverage;}@Overridepublic String getDescription() {return mBeverage.getDescription() + ", Milk";}public double cost() {return mCost + mBeverage.cost();}}
StarbuzzCoffee.java
public class StarbuzzCoffee {public static void main(String[] args) {Beverage beverage = new Espresso();System.out.println(beverage.getDescription() + " $" + beverage.cost());Beverage beverage2 = new DarkRoast();beverage2 = new Mocha(beverage2);beverage2 = new Mocha(beverage2);beverage2 = new Whip(beverage2);System.out.println(beverage2.getDescription() + " $" + beverage2.cost());Beverage beverage3 = new HouseBlend();beverage3 = new Soy(beverage3);beverage3 = new Mocha(beverage3);beverage3 = new Whip(beverage3);System.out.println(beverage3.getDescription() + " $" + beverage3.cost());}}
運行圖例:
源碼下載:
http://download.csdn.net/detail/u013761665/8721015
Java設計模式——裝飾者模式