在Decorator設計模式中,我們有一個ItemClass(p.e. Coffee),然後是包含對Coffee的引用的AbstractDecorator(p.e. CoffeeDecorator)以及ConcreteDecorators(例如milk)。我的問題是,爲什麼我們需要AbstractDecorator類,爲什麼不直接從Coffee類繼承Concrete Decorators?或者爲什麼我們沒有包含ItemClass屬性的接口,如果我們已經想確保ConcreteDecorators對ItemClass有引用?使用這個AbstractDecorator,我們只是禁用了一個選項,我們的ConcreteDecorators繼承了其他一些類。提前致謝!Decorator模式中使用抽象Decorator類
6
A
回答
1
我們使用抽象類去除具體類中的重複。在裝飾器模式中,您有重複存儲裝飾對象實例並將調用傳遞給它。如果你不會將這個邏輯移動到基礎(抽象)裝飾器,那麼你需要在每個具體的裝飾器中實現這個。
考慮以下飲料接口:
public interface IBeverage
{
decimal Price { get; }
string Description { get; }
}
這是由咖啡來實現:
public class Coffee : IBeverage
{
public decimal Price
{
get { return 3.5M; }
}
public string Description
{
get { return "Coffee"; }
}
}
現在要創建咖啡第一裝飾。您目前不需要創建抽象裝飾器。讓我們的牛奶蜂免費。只需編寫你需要的最簡單的代碼:
public class Milk : IBeverage
{
private readonly IBeverage _beverage;
public Milk(IBeverage beverage)
{
_beverage = beverage;
}
public decimal Price
{
get { return _beverage.Price; } // price not changed
}
public string Description
{
get { return _beverage.Description + " with milk"; }
}
}
現在你需要另一個裝飾器。讓它成爲奶油:
public class Cream : IBeverage
{
private readonly IBeverage _beverage;
public Cream(IBeverage beverage)
{
_beverage = beverage;
}
public decimal Price
{
get { return _beverage.Price + 2M; }
}
public string Description
{
get { return _beverage.Description + " with cream"; }
}
}
你可以看到重複的代碼。所以,現在是重構的時候了。讓我們繼續重複的代碼,以抽象基裝飾類,它負責將舉辦參照裝飾飲料並通過調用它:
public abstract class BeverageDecorator : IBeverage
{
private readonly IBeverage _beverage;
public BeverageDecorator(IBeverage beverage)
{
_beverage = beverage;
}
public virtual decimal Price
{
get { return _beverage.Price; }
}
public virtual string Description
{
get { return _beverage.Description; }
}
}
現在你可以重寫只有那些行爲由你的裝飾改變了電話。牛奶裝飾將看起來像:
public class Milk : BeverageDecorator
{
public Milk(IBeverage beverage)
: base(beverage)
{
}
public override string Description
{
get
{
return base.Description + " with milk";
}
}
}
更清潔,是嗎?這就是我們使用基礎裝飾器的原因。
相關問題
- 1. 類似Decorator模式Redux的表象性
- 2. MVC與Decorator模式
- 3. Decorator模式與調用超反模式
- 4. Decorator模式和泛型
- 5. 設計模式:Builder + Decorator + Composite
- 6. Decorator模式 - 從裝飾
- 7. 在Decorator模式爲何抽象的裝飾需要抽象組件
- 8. Decorator模式的類的許多屬性
- 9. Ecore decorator
- 10. Decorator模式鏈方法如何調用?
- 11. Ninject依賴注入Decorator模式
- 12. Decorator模式是否適合您?
- 13. 帶參數的Python Decorator類
- 14. `decorator'類的好名字?
- 15. CDI:@Decorator @Stateless
- 16. python singleton class decorator
- 17. Japura Swing - Decorator
- 18. 這是Decorator模式的示例(將數據添加到對象)?
- 19. Big Query @ 0 table decorator
- 20. 將類應用到客戶Zend Decorator
- 21. Java庫中是否有Decorator類?
- 22. 您對Decorator模式使用什麼命名約定?
- 23. 在擴展RecyclerView.Adapter的同時使用Decorator模式是否合適?
- 24. python class decorator不起作用
- 25. 要使用多線程,Command模式比Decorator模式更有用嗎?
- 26. rspec使用draper測試視圖Decorator
- 27. 使用@ admin.register在Django Admin中錄製類decorator
- 28. Decorator模式有什麼用處?我的例子不工作
- 29. Python3 - 通過decorator-繼承
- 30. Java,Base64:如何使用Decorator編寫Base64OutputStream類型
好的,我同意。但是,這不是一個小的代價,如果你現在有這樣的奢侈品,那麼你的具體裝飾者可以在需要時實現其他類嗎?我仍然試圖讓這種模式正確,所以我可能錯過了什麼? – Marko
好吧,現在看着你的代碼,我意識到有更多的好處,比設置一個對象的引用來裝飾...這種方式你封裝所有的具體裝飾相同的行爲。但是,我的腦海裏仍然有一種聲音說,如果你可以讓那些具體的裝飾器打開實施,那將是一件好事。:) – Marko
@breakpoint抱歉,沒有得到解決。複製總是邪惡的,所以你需要避免它。您不必強制從抽象裝飾器繼承所有裝飾器。如果其中一個具體的裝飾器應該實現其他類,則從其他類繼承並直接實現IB平衡。順便說一下,這是非常奇怪的要求,從其他一些類繼承。考慮在這種情況下使用組合而不是繼承。 –