设计模式09: Decorator 装饰模式(结构型模式)
生活随笔
收集整理的這篇文章主要介紹了
设计模式09: Decorator 装饰模式(结构型模式)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Decorator 裝飾模式(結構型模式)
子類復子類,子類何其多
加入我們需要為游戲中開發一種坦克,除了不同型號的坦克外,我們還希望在不同場合中為其增加以下一種多種功能:比如紅外線夜視功能,比如水路兩棲功能,比如衛星定位功能等等。
問題代碼:
/// <summary>/// 抽象坦克/// </summary>public abstract class Tank{public abstract void Shot();public abstract void Run();} //各種型號public class T50 : Tank{public override void Shot(){//... }public override void Run(){//... }}public class T75 : Tank{public override void Shot(){//... }public override void Run(){//... }} /// <summary>/// 紅外線夜視/// </summary>public interface IA{//... }/// <summary>/// 水陸兩棲/// </summary>public interface IB{//... } //各種不同功能組合public class T50A : T50, IA{//... }public class T50B : T50, IB{//... }public class T50AB : T50,IA,IB{//...}?
動機(Motivation)
上述描述的問題根源在于我們“過度的使用繼承來擴展對象的功能”,由于繼承為類引入的靜態特質,使得這種擴展方式缺乏靈活性;并且隨著子類的增多(擴展功能的增多),各種子類組合(擴展功能的組合)會導致更多子類的膨脹(多繼承)。
如何使“對象功能的擴展”能夠根據需求來動態地(運行時)實現?同時避免“擴展功能增多”帶來的子類膨脹問題?從而使得任何“功能擴展變化”所導致的影響降為最低?
?
意圖(Intent)
動態地給一個對象增加一些額外的職責。就增加功能而言,Decorator模式比生成子類更為靈活。——《實際模式》GoF
?
實例代碼:
/// <summary>/// 抽象坦克/// </summary>public abstract class Tank{public abstract void Shot();public abstract void Run();}?
//各種型號public class T50 : Tank{public override void Shot(){//... }public override void Run(){//... }}public class T75 : Tank{public override void Shot(){//... }public override void Run(){//... }}?
public abstract class Decorator : Tank//接口繼承,抽象類可以看做接口 {private Tank tank;//Has-A對象組合public Decorator(Tank tank){this.tank = tank;}public override void Shot(){tank.Shot();}public override void Run(){tank.Run();}}?
/// <summary>/// 紅外功能擴展/// </summary>public class DecoratorA : Decorator{public DecoratorA(Tank tank):base(tank){}public override void Shot(){//紅外功能擴展//do shot...base.Shot();}public override void Run(){//紅外功能擴展//do run...base.Run();}}?
/// <summary>/// 水陸兩棲功能擴展/// </summary>public class DecoratorB : Decorator{public DecoratorB(Tank tank):base(tank){}public override void Shot(){//水陸兩棲功能擴展//do shot...base.Shot();}public override void Run(){//水陸兩棲功能擴展//do run...base.Run();}}?
class App{public static void Main(){Tank tank=new T50();DecoratorA da = new DecoratorA(tank);//紅外功能擴展DecoratorB db = new DecoratorB(da);//紅外、水陸兩棲功能擴展 }}?
?
Decorator模式的幾個要點
- 通過采用組合,而非繼承的手法,Decorator模式實現了在運行時動態地擴展對象功能的能力,而且可以根據需要擴展多個功能。避免了單獨使用繼承帶來的“靈活性差”和“多子類衍生問題”。
- Tank類在Decorator模式中充當抽象接口的角色,不應該去實現具體的行為。而且Decorator類對于Tank類應該是透明——換言之Tank類無需知道Decorator,Decorator類是從外部來擴展Tank類的功能。
- Decorator類在接口上表現為is-a Tank類的繼承關系,即Decorator繼承了Tank類所具有的接口。在實現上又表現為has-a Tank的組合關系,即Decorator類又使用了另一個Tank類。我們可以使用一個或者多個Decorator對象來“裝飾”一個Tank對象,而且裝飾后的對象仍然是Tank對象。
- Decorator模式并非解決“多子類衍生的多繼承”問題,Decorator模式應用的要點在于解決“主體類在多個方向上的擴展功能”——是為“裝飾”的含義。
?
轉載于:https://www.cnblogs.com/jesselzj/p/4723910.html
總結
以上是生活随笔為你收集整理的设计模式09: Decorator 装饰模式(结构型模式)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHP预定义常量DIRECTORY_SE
- 下一篇: BZOJ 1042 [HAOI2008]