裝飾模式(Decorator):動態地給一個物件新增一些額外的職責,就增加功能來說,裝飾模式比生成子類更為靈活。
裝飾模式結構圖:
裝飾模式實現程式碼:
/// <summary> /// 宣告一個Component的抽象基類 /// </summary> abstract class Component { public abstract void Operation(); } /// <summary> ///宣告一個具體的Component,繼承Component /// </summary> class ConcreteComponent : Component { public override void Operation() { Console.WriteLine("ConcreteComponent.Operation()"); } } /// <summary> /// 宣告一個抽象的裝飾類'Decorator' /// 並繼承Component /// </summary> abstract class Decorator : Component { protected Component component; //裝飾方法 public void SetComponent(Component component) { this.component = component; } //重寫 Operation 方法 public override void Operation() { if (component != null) { component.Operation(); } } } /// <summary> /// 宣告一個具體裝飾類A,繼承Decorator /// </summary> class ConcreteDecoratorA : Decorator { public override void Operation() { //一些功能擴充套件 Console.WriteLine("ConcreteDecoratorA.Operation()"); base.Operation(); } } /// <summary> /// 宣告一個具體裝飾類B,繼承Decorator /// </summary> class ConcreteDecoratorB : Decorator { public override void Operation() { //一些功能擴充套件 AddedBehavior(); Console.WriteLine("ConcreteDecoratorB.Operation()"); base.Operation(); } //裝飾類B自有方法 void AddedBehavior() { } } class Program { static void Main(string[] args) { ConcreteComponent c = new ConcreteComponent(); ConcreteDecoratorA d1 = new ConcreteDecoratorA(); ConcreteDecoratorB d2 = new ConcreteDecoratorB(); d1.SetComponent(c); d2.SetComponent(d1); d2.Operation(); Console.ReadKey(); } }
執行結果:
我們可以通過一個簡單是例項,還應用一下裝飾模式,比如現在有一種坦克,坦克有很多的型號和特色,有的具有紅外功能,有的具有GPS定位功能,通過使用裝飾模式,大大降低了子類的膨脹。
//坦克基類 public class Tank { /// <summary> /// 射擊 /// </summary> public virtual void Shoot() { } } //T50 型坦克 public class T50Tank:Tank { public override void Shoot() { Console.WriteLine("T50 型號坦克射擊"); } } //T51型坦克 public class T51Tank : Tank { public override void Shoot() { Console.WriteLine("T51 型號坦克射擊"); } } //裝飾基類 public abstract class Decorator : Tank { protected Tank tank; //利用構造器進行裝飾 public Decorator(Tank tank) { this.tank = tank; } public override void Shoot() { if (tank != null) { tank.Shoot(); } } } //具有紅外功能 public class InfraRed : Decorator { public InfraRed(Tank tank) : base(tank) { } public override void Shoot() { Console.WriteLine("帶紅外功能"); base.Shoot(); } } //具有GPS功能 public class GPS : Decorator { public GPS(Tank tank) : base(tank) { } public override void Shoot() { Console.WriteLine("帶GPS功能"); base.Shoot(); } } class Program { static void Main(string[] args) { //宣告一個T50型坦克 Tank t50Tank = new T50Tank(); //給T50型坦克賦予紅外功能 InfraRed red = new InfraRed(t50Tank); //給T50型坦克賦予GPS功能 GPS gps = new GPS(red); gps.Shoot(); Console.ReadKey(); } }
執行結果: