2012-09-28 80 views
2

書中'首先設計模式',裝飾者章節,它討論了當裝飾者處理具體類型和導致問題時的問題。我在本章中複製了一些Q & A:裝飾設計模式問題?

問:我有點擔心代碼可能會針對特定的具體組件(比如HouseBlend)進行測試,然後執行某些操作,如發出折扣。一旦我用修飾器包裝了HouseBlend,這不會再起作用。

答:完全正確。如果您的代碼依賴於具體組件的類型,裝飾器將會破壞該代碼。只要您只針對抽象組件類型編寫代碼,裝飾器的使用對您的代碼將保持透明。但是,一旦開始編寫針對具體組件的代碼,您將需要重新考慮應用程序設計和使用裝飾器。

有人可以給一個簡單的例子,說明'客戶'代碼是針對具體類型還是抽象類型寫的?前者如何給裝飾者帶來麻煩?

書中裝飾的樣本測試代碼是這樣的:

public class StarbuzzCoffee { 
    public static void main(String args[]) { 
     Beverage beverage2 = new DarkRoast(); 
     beverage2 = new Mocha(beverage2); 
     beverage2 = new Mocha(beverage2); 
     beverage2 = new Whip(beverage2); 
     System.out.println(beverage2.getDescription() 
      + 「 $」 + beverage2.cost()); 
     ... 
    } 
} 

寫入反對抽象類型此測試代碼(也是一種客戶端代碼)?

感謝,

回答

1

他們談論的是檢查beverage2類型代碼,例如

if (beverage2 instanceof DarkRoast) { 
    <do_something> 
} 

一旦你用摩卡或鞭裝飾beverage2,它不是在DarkRoast了。

編輯:我還要提一下,instanceof的使用經常表明一個糟糕的設計,並沒有最大限度地利用OO,也就是說它在某些情況下很有用。

0

只要你只寫反對抽象組件類型代碼,使用裝飾將保持透明,以你的代碼

是。這是它應該的方式。

您不應該修飾特定於具體裝飾器實現的新功能。一旦你做到了,裝飾者模式的目的就失去了。

由於包含接口本身的抽象裝飾器(使用組合),裝飾器模式運行良好。它有助於減少不同口味的不同組合的數量。

我實施了Decorator模式的類似用例。看看這個文檔鏈接

When to Use the Decorator Pattern?

Beverage beverage = new SugarDecorator(new LemonDecorator(new Tea("Assam Tea"))); 
beverage.buildBeverage(); 

你會得到18個輸出這是Tea (10) + Lemon (5) + Sugar (3)總和:

Cost of:Assam Tea+Lemon +Sugar :18 

對於上面的例子中工作,你需要在抽象的一些變化Decorator如文檔鏈接中所述。由於抽象類BeverageDecorator的組成,可以很容易地添加多種口味。

你不應該添加基於混凝土裝飾者的業務邏輯。你在代碼中加入了Concrete Decorator的智能,你就失去了獨立增加動態職責的靈活性。