根據需要擴展多個功能。避免單獨使用繼承而產生靈活性差和"多子類別衍生問題。但它最根本的作用是在於裝飾。
例如開發一個報表功能可能只有顯示和下載的兩個功能,
之後又要加入顯示時先檢查是否有權限、下載前也要檢查權限、權限檢查後,判斷系統日期是否為月底。
所以為了要解決新增功能問題,不要修改原本的程式碼,又可以擴充,Decorator就是符合開發封閉原則,對修改封閉,對擴充開放,
藉以降低系統可能的錯誤風險,使用Decorator模式的組合特性來達到動態擴充相關功能。
假如在遊戲中開發一種坦克,除了各種不同型號的坦克外,還希望在不同場合中增加一種或多種功能,比如紅外線夜視、水陸兩棲,衛星定位等等。
建立抽象坦克類別
namespace Decorator
{
public abstract class Tank
{
public abstract void Shot();
public abstract void Run();
}
}
namespace Decorator
{
public class T50 : Tank
{
public override void Shot()
{
Console.WriteLine("T50坦克平均每秒射擊5發子彈");
}
public override void Run()
{
Console.WriteLine("T50坦克平均每時運行30公里");
}
}
}
然後按照上面的結構,一樣創造了T75、790的場克,功能結構也是依不同的功能性而產生不同的陳述結構
實現介面繼承,非實現繼承,組合物件
namespace Decorator
{
public abstract class Decorator : Tank
{
private Tank tank;
public Decorator(Tank tank)
{
this.tank = tank;
}
public override void Shot()
{
tank.Shot();
}
public override void Run()
{
tank.Run();
}
}
}
產生各種不同的功能並擴展,同時可依需求限制其功能,讓各種不同的坦克有等級上的差別
namespace Decorator
{
public class DecoratorA : Decorator
{
public DecoratorA(Tank tank)
: base(tank)
{
}
public override void Shot()
{
//功能擴展 且有紅外功能
base.Shot();
}
public override void Run()
{
base.Run();
}
}
}
class Program
{
static void Main(string[] args)
{
Tank tank = new Tank();
DecoratorA da = new DecoratorA(tank); //且有紅外功能
DecoratorB db = new DecoratorB(da); //且有紅外和水陸兩棲功能
DecoratorC dc = new DecoratorC(db); //且有紅外、水陸兩棲、衛星定們三種功能
dc.Shot();
dc.Run();
}
}
Decorator需要擴展一個類的功能,或給一個類增加附加責任,動態地給一個物件增加功能,這些功能可以動態撤銷。也可以增加由一些基本功能的排列組合而產生的非常大量的功能。
Decorator在.NET(Stream)中的應用,透過.Net讓Decorator模式省略了抽象裝飾角色(Decorator):
下面的程式中BufferedStream擴展了緩衝的功能、CryptoStream擴展了緩衝,加密的功能:
class Program
{
public static void Main(string[] args)
{
MemoryStream ms = new MemoryStream (new byte[] { 100, 456, 864, 222, 567 });
BufferedStream BufferedStream buff = new BufferedStream(ms);
CryptoStream CryptoStream crypto = new CryptoStream(buff);
}
}
所以透過.NET的Library呈現,可以看到BufferedStream是繼承於Stream類別,依然可以達到同樣的效果。
-雲遊山水為知已逍遙一生而忘齡- 電腦神手
沒有留言:
張貼留言