1. 程式人生 > >C# - 設計模式 - 裝飾者模式

C# - 設計模式 - 裝飾者模式

private 實現類 comm 回路 匯總 abs round C# 由於

裝飾者模式

問題場景

如果要計算一杯咖啡的價格,只需要調用其獲取價格的方法就可以了,但是如果需要加一些材料,比如牛奶、巧克力、糖等等,這些材料也必須返回它們價格以便於用於匯總計算,但是材料有很多,我們並不能事先預測買家需要哪些材料,所以似乎只能在咖啡類中做出判定去確認買家需要的材料後才能計算出結果,但這並不是一個好的解決思路,由於材料可能有上100種,我們不可能寫100次判斷去確認加的是哪些材料,況且今後有新進的材料,還得繼續多處修改代碼。解決方式是使用抽象類和包裝器,抽象類提供可重寫的獲取價格的方法,由飲料子類去實現自身的價格,而材料也可以從同一個抽象類派生,這樣,飲料類只需要返回自身的價格,而材料類則依賴於抽象類的實現(飲料類),調用抽象類的獲取價格的方法並加上材料自身的價格就可以在外部調用材料時計算出總價格。

總結模式

在不改動類型結構的情況下,只利用現有代碼為類型附加其它的功能。裝飾者也叫包裝器,包裝器需要依賴一個抽象類的具體實現類,以便調用依賴對象的方法獲取結果。

代碼示例

namespace AppCUI
{
//超類
public abstract class Drink
{
public abstract double GetPrice( );
}

//具體的飲料
public class Coffe : Drink
{
//返回自身的價格
public override double GetPrice(
)

{
return 12.5;
}
}

//具體的材料也從飲料派生,以便重寫價格
public class Milk : Drink
{
//飲料的價格需要附加我的價格,所以我需要得到飲料,以便計算總價格
private Drink drink;

//飲料抽象的具體類通過構造函數註入給我
public Milk( Drink drink )
{
this.drink = drink;
}

//計算總價格
public
override double GetPrice( )

{
return 1.2 + drink.GetPrice( );
}
}

public class Chocolate : Drink
{
private Drink drink;

public Chocolate( Drink drink )
{
this.drink = drink;
}

public override double GetPrice( )
{
return 1.5 + drink.GetPrice( );
}
}

public class Programe
{
static void Main( string[] args )
{
Drink drink = new Coffe( ); //我要一杯咖啡
drink = new Milk( drink ); //咖啡需要加牛奶
drink = new Chocolate( drink ); //牛奶咖啡需要加糖
Console.WriteLine( drink.GetPrice( ) ); //巧克力內部維護了牛奶咖啡的價格,牛奶維護了咖啡的價格,返回路徑:咖啡價格=>牛奶+咖啡價格=>巧克力+牛奶咖啡價格
}
}
}

  

C# - 設計模式 - 裝飾者模式