2012-08-26 61 views
6

有人可以請我通過使用構造函數注入另一個類而不是類繼承創建裝飾類的區別(如同在好處中)嗎?在我能想到的例子中,我可能以兩種方式之一完成相同的最終目標,但我懷疑我缺少一些基本的東西。通過構造函數注入裝飾與簡單繼承

回答

4

裝飾者模式涉及構成的一個對象。爲了能夠繼承該對象的類型,它顯然必須是可繼承的。並非所有的類型都是爲了繼承而設計的,也就是說,它們的目的是作爲基類,即使它們從純粹的技術觀點可以繼承(我認爲這是一個設計缺陷)。

裝飾者模式的存在理由是能夠在不修改對象本身的情況下修改對象的行爲。通過繼承,你基本上修改了對象本身,然後你通過多態來定期改變行爲,這意味着你沒有完成同樣的事情。

因此,裝飾和繼承都有其用途。使用裝修時,這些人是真正的

  • 你不能繼承(例如,如果類是sealed在C#)
  • 你不應該繼承(類顯然並不意味着是一個基類)
  • 你想(通過與不同行爲的裝飾包裹它)來改變一個特定對象多次行爲

注意繼承是最有力的工具存在於二OO工具箱。擁有巨大的權力會帶來很大的責任,這並不總是很容易處理。我會說:總是撰寫或彙總。當無法完成時,繼承。如果你不能繼承,更努力地嘗試撰寫或聚合「

+0

精彩的解釋! – goldfinger

0

我將恢復如下:?

當你要繼承

當對象是來自同一個語義層次和代表一個是,一個關係。

這是什麼意思嗎?

是-aFeline,確實是Feline是-aVertebrate等等。

你應該什麼時候裝飾?

當對象不代表is-a的關係。但是,是的,CoffeeMilk都可以位於同一層次。但是,如果你were to sell Cappuccino你不會說咖啡是-al牛奶,而不是你用Milk裝飾它。

結論:

Is-a是從has-a不同。一種是亞型,另一種是部分的組成。

可是,看到以下內容:https://stackoverflow.com/questions/1621344/head-first-design-patterns-decorator-pattern

一個真實世界的例子,是爲了使ACL檢查,爲您的控制器或服務security container as a Decorator

0

裝飾的另一個非常好的理由是,它給你選擇裝飾接口而不是類。然後你變得非常鬆散耦合,並且可以在不編寫更多代碼的情況下將正交裝飾行爲添加到接口的多個實現。