裝飾模式(Decorator Pattern) :動態地給一個對象增長一些額外的職責(Responsibility),就增長對象功能來講,裝飾模式比生成子類實現更爲靈活。其別名也能夠稱爲包裝器(Wrapper),與適配器模式的別名相同,但它們適用於不一樣的場合。根據翻譯的不一樣,裝飾模式也有人稱之爲「油漆工模式」,它是一種對象結構型模式。git
Component類:github
namespace DecoratorPattern.BasicStructure { /// <summary> /// 抽象組件類 /// </summary> abstract class Component { public abstract void Operation(); } }
ConcreteComponent類:編程
namespace DecoratorPattern.BasicStructure { /// <summary> /// 具體組件類 /// </summary> class ConcreteComponent : Component { public override void Operation() { Console.WriteLine("具體對象的操做"); } } }
Decorator類:app
namespace DecoratorPattern.BasicStructure { /// <summary> /// 裝飾抽象類 /// </summary> abstract class Decorator : Component { protected Component Component { get; set; } public void SetComponent(Component component) { this.Component = component; } public override void Operation() { if (Component != null) { Component.Operation(); } } } }
ConcreteDecoratorA類:ide
namespace DecoratorPattern.BasicStructure { /// <summary> /// 具體裝飾類 A /// </summary> class ConcreteDecoratorA : Decorator { private string _addedState; public override void Operation() { base.Operation(); _addedState = "new state"; Console.WriteLine("具體裝飾對象A的操做"); } } }
ConcreteDecoratorB類:學習
namespace DecoratorPattern.BasicStructure { /// <summary> /// 具體裝飾類 B /// </summary> class ConcreteDecoratorB : Decorator { public override void Operation() { base.Operation(); AddedBehavior(); Console.WriteLine("具體裝飾對象B的操做"); } private void AddedBehavior() { } } }
客戶端調用代碼:this
static void Main(string[] args) { try { {//BasicStructure ConcreteComponent c = new ConcreteComponent(); ConcreteDecoratorA d1 = new ConcreteDecoratorA(); ConcreteDecoratorB d2 = new ConcreteDecoratorB(); d1.SetComponent(c); d2.SetComponent(d1); d2.Operation(); } } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.ReadKey(); }
結果以下:spa
場景模擬:某人最近新買了一部蘋果XS,因而準備給手機貼膜和買個手機套帶。翻譯
Handset(手機抽象)類——Component類設計
namespace DecoratorPattern.SituationSimulation { /// <summary> /// 手機抽象類,即裝飾者模式中的抽象組件類 /// </summary> abstract class Handset { public abstract void Operation(); } }
AppleHandset(蘋果手機)類——ConcreteComponent類
namespace DecoratorPattern.SituationSimulation { /// <summary> /// 蘋果手機手機類,即裝飾着模式中的具體組件類 /// </summary> class AppleHandset : Handset { public override void Operation() { Console.WriteLine("操做蘋果手機"); } } }
HandsetDecorator(手機裝飾)類——Decorator類
namespace DecoratorPattern.SituationSimulation { abstract class HandsetDecorator : Handset { protected Handset Handset { get; set; } public HandsetDecorator(Handset handset) { this.Handset = handset; } public override void Operation() { if (Handset != null) { Handset.Operation(); } } } }
HandsetSticker(手機貼膜)類——ConcreteDecorator類
namespace DecoratorPattern.SituationSimulation { /// <summary> /// 貼紙 /// </summary> class HandsetSticker : HandsetDecorator { public HandsetSticker(Handset handset) : base(handset) { } public override void Operation() { base.Operation(); AddSticker(); } public void AddSticker() { Console.WriteLine("給手機貼膜"); } } }
HandsetCasing(手機保護套)類——ConcreteDecorator類
namespace DecoratorPattern.SituationSimulation { /// <summary> /// 手機保護套 /// </summary> class HandsetCasing : HandsetDecorator { public HandsetCasing(Handset handset) : base(handset) { } public override void Operation() { base.Operation(); AddCasing(); } public void AddCasing() { Console.WriteLine("給手機戴保護套"); } } }
客戶端調用代碼:
static void Main(string[] args) { try { {//SituationSimulation //第一種寫法 Console.WriteLine("***************第一種寫法:***************"); AppleHandset handset = new AppleHandset(); HandsetSticker handsetSticker = new HandsetSticker(handset); HandsetCasing handsetCasing = new HandsetCasing(handsetSticker); handsetCasing.Operation(); //第二種寫法 Console.WriteLine("***************第二種寫法:***************"); Handset appleHandset = new AppleHandset(); appleHandset = new HandsetSticker(appleHandset); appleHandset = new HandsetCasing(appleHandset); appleHandset.Operation(); //第二種寫法的簡化 Console.WriteLine("***************第二種寫法的簡化:***************"); new HandsetCasing(new HandsetSticker(new AppleHandset())).Operation(); } } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.ReadKey(); }
結果以下:
在如下狀況下可使用裝飾模式: