本篇部落格我們接著上篇部落格(設計模式(4)一——行為型模式1)我們繼續。
19.中介者模式
用一個中介對象來封裝一系列的對象互動。中介者使各對象不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變他們之間的互動。其實將對象之間的互動封裝起來就是中介者。使對象之間沒有互動,只需將對象自己的通知和中介者互動即可。與面板模式有類似的地方。(舉個例子:在公司領導就是下級的中介者,下級有問題不能解決不用在下級之間來回的問,直接去找領導(中介者)就可以快速的解決問題)
UML圖:
代碼:
namespace 中介者模式{ class Program { static void Main(string[] args) { ConcreteMediator m = new ConcreteMediator(); ConcreteColleague1 c1 = new ConcreteColleague1(m); ConcreteColleague2 c2 = new ConcreteColleague2(m); m.Colleague1 = c1; m.Colleague2 = c2; c1.Send("吃飯了嗎?"); c2.Send("沒有呢,你打算請客嗎?"); Console.Read(); } } abstract class Mediator //抽象中介者 { public abstract void Send(string message, Colleague colleague); } abstract class Colleague //抽象同事 { protected Mediator mediator; public Colleague(Mediator mediator) { this.mediator = mediator; } } class ConcreteMediator : Mediator //具體的中介者 { private ConcreteColleague1 colleague1; private ConcreteColleague2 colleague2; //設定兩個具體交流的同事 public ConcreteColleague1 Colleague1 { set { colleague1 = value; } } public ConcreteColleague2 Colleague2 { set { colleague2 = value; } } public override void Send(string message, Colleague colleague) { if (colleague == colleague1) { colleague2.Notify(message); //得到資訊 } else { colleague1.Notify(message ); } } } class ConcreteColleague1:Colleague //具體的同事 { public ConcreteColleague1(Mediator mediator):base(mediator) {} public void Send(string message) //本人發送訊息 { mediator.Send(message,this); } public void Notify(string message) //接受到訊息 { Console.WriteLine("同事1得到資訊:"+message ); } } class ConcreteColleague2:Colleague //具體的同事 { public ConcreteColleague2(Mediator mediator):base(mediator) {} public void Send(string message) //本人發送訊息 { mediator.Send(message,this); } public void Notify(string message) //接受到訊息 { Console.WriteLine("同事2得到資訊:"+message ); } }}
20. 訪問者模式
表示一個作用於某對象結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。適用於資料結構相對穩定的系統,目的是把處理從資料結構中分離出來,增加新的操作(訪問者)很容易,訪問者模式就是將有關的行為集中到一個訪問者對象中。增加新的資料結構比較困難。(舉個例子:北京動物園有很多景點供遊客(訪問者)參觀,不同的訪問者看了不同的景點之後有不同的反應,我看了猴子之後感覺挺好,你看了之後感覺可能不好;我看了大象表演之後可能感覺想吐,你看了之後還津津有味的)
UML圖:
代碼:
namespace 訪問者模式{ class Class2 { static void Main(string[] args) { ObjectStructure1 o = new ObjectStructure1(); o.Attach(new ConcreteElementA()); o.Attach(new ConcreteElementB()); ConcreteVisitor1 v1 = new ConcreteVisitor1(); ConcreteVisitor2 v2 = new ConcreteVisitor2(); o.Accept(v1); o.Accept(v2); Console.Read(); } } abstract class Visitor { public abstract void VisitConcreteElementA(ConcreteElementA concreteElementA); public abstract void VisitConcreteElementB(ConcreteElementB concreteElementB); } class ConcreteVisitor1 : Visitor { public override void VisitConcreteElementA(ConcreteElementA concreteElementA) { Console.WriteLine("{0}被{1}訪問1",concreteElementA.GetType().Name ,this.GetType().Name ); } public override void VisitConcreteElementB(ConcreteElementB concreteElementB) { Console.WriteLine("{0}被{1}訪問1", concreteElementB.GetType().Name, this.GetType().Name); } } class ConcreteVisitor2 : Visitor { public override void VisitConcreteElementA(ConcreteElementA concreteElementA) { Console.WriteLine("{0}被{1}訪問2", concreteElementA.GetType().Name, this.GetType().Name); } public override void VisitConcreteElementB(ConcreteElementB concreteElementB) { Console.WriteLine("{0}被{1}訪問2", concreteElementB.GetType().Name, this.GetType().Name); } } abstract class Element { public abstract void Accept(Visitor visitor); } class ConcreteElementA : Element { public override void Accept(Visitor visitor) { visitor.VisitConcreteElementA(this ); } public void OperationA() //其他相關函數 { } } class ConcreteElementB : Element { public override void Accept(Visitor visitor) { visitor.VisitConcreteElementB(this); } public void OperationA() //其他相關函數 { } } class ObjectStructure1 { private IList<Element> elements = new List<Element>(); public void Attach(Element element) { elements.Add(element ); } public void Detach(Element element) { elements.Remove(element); } public void Accept(Visitor visitor) { foreach (Element e in elements) { e.Accept(visitor); } } }}
21. 策略模式
定義了演算法家族,分別封裝起來,讓他們之間可以相互替換,此模式讓演算法的變化,不會影響到使用演算法的客戶。策略模式是一種定義一系列演算法的方法,簡化了單元測試,每個演算法都有自己的類,可以通過自己的介面單獨測試。簡單的說策略模式就是用來封裝演算法的,是演算法的實現細節得到隱藏。(舉個例子:在我們剛剛試航成功的瓦良格號航空母艦上配有最新的近程防空系統,在這個系統中可以放很多飛彈,你可以放“X-29”、“X-15”、“KH-101”等不同型號)
UML圖:
代碼:
// 策略模式:定義演算法家族,分別封裝起來,讓他們之間可以互相替換(父類和子類繼承),此模式讓演算法的變化,不會影響到使用演算法的客戶// 再使用另一個類通過參數的傳遞引用策略類namespace 策略模式{ class Class1 { static void Main(string[] args) { Context context; context=new Context(new ConcreateStrategyA()); context.ContextInterface(); context=new Context(new ConcreateStrategyB()); context.ContextInterface(); context=new Context(new ConcreateStrategyC()); context.ContextInterface(); Console.Read(); } } abstract class Strategy //策略類,抽象演算法類 { public abstract void AlgorithmInterface(); } class ConcreateStrategyA : Strategy //具體演算法A { public override void AlgorithmInterface() { Console.WriteLine("演算法A的實現"); } } class ConcreateStrategyB : Strategy //具體演算法B { public override void AlgorithmInterface() { Console.WriteLine("演算法B的實現"); } } class ConcreateStrategyC : Strategy //具體演算法C { public override void AlgorithmInterface() { Console.WriteLine("演算法C的實現"); } } class Context //維護一個對Strategy對象的引用 { Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } public void ContextInterface() { strategy.AlgorithmInterface(); } }}
22. 備忘錄模式
在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外儲存這個狀態。這樣以後就可以將該對象恢複到原來儲存的狀態。這種模式比較適合於功能比較複雜,但是需要維護或記錄屬性曆史的類。(舉個例子:玩遊戲的時候,自己死了都希望回到前一段時間的狀態,只要儲存好一個時間點的狀態,就可以恢複到這個時間的狀態)
UML圖:
代碼:
namespace 備忘錄模式{ class Class2 { static void Main(string[] args) { //大戰前 GameRole1 lixiaoyao = new GameRole1(); lixiaoyao.GetInitState(); lixiaoyao.StateDisplay(); //儲存進度 RoleStateCaretaker stateAdmin = new RoleStateCaretaker(); stateAdmin.Memento = lixiaoyao.SaveState(); //大戰時,損失嚴重 lixiaoyao.Fight(); lixiaoyao.StateDisplay(); //恢複之前的狀態 lixiaoyao.RecoveryState(stateAdmin.Memento); lixiaoyao.StateDisplay(); Console.Read(); } } class GameRole1:GameRole //遊戲角色 { //儲存角色狀態 public RoleStateMemento SaveState() { return (new RoleStateMemento(vit,atk,def ) ); } //恢複角色狀態 public void RecoveryState(RoleStateMemento memento) { this.vit = memento.Vitality; this.atk = memento.Attack; this.def = memento.Defense; } } class RoleStateMemento //角色狀態儲存箱 { private int vit; private int atk; private int def; public RoleStateMemento(int vit,int atk,int def) { this.vit=vit ; this.atk=atk ; this.def =def; } public int Vitality //生命力 { get{return vit ;} set{vit =value ;} } public int Attack //攻擊力 { get{return atk;} set{atk=value ;} } public int Defense { get{return def;} set{def=value ;} } } class RoleStateCaretaker //角色狀態管理者 { private RoleStateMemento memento; public RoleStateMemento Memento { get{return memento;} set{memento =value ;} } }}
23. 迭代器模式
提供一種方法順序訪問一個彙總對象中各個元素,而不是暴露該對象的內部表示。一個聚集對象,不管這些對象時什麼都需要遍曆的時候,就應該考慮使用迭代器模式。,為遍曆不同的聚集結構提供開始、下一個、是否結束、當前是那一項等。(舉個例子:我們去火車站到候車廳的時候,每個人的行李都會被門口的那個東東(迭代器)檢測一遍,防止我們帶雷管、炸藥、自殺性武器等)
UML圖:
代碼:
//20.3 迭代器的實現namespace 迭代器模式{ class Program { static void Main(string[] args) { ConcreteAggregate a = new ConcreteAggregate(); a[0] = "大鳥"; a[1] = "小菜"; a[2] = "行李"; a[3] = "老外"; a[4] = "公交內部員工"; a[5] = "小偷"; //Iterator i = new ConcreteIterator(a); Iterator i = new ConcreteIteratorDesc(a); object item = i.First(); while (!i.IsDone()) { Console.WriteLine("{0}請買票下車",i.CurrentItem()); i.Next(); } Console.Read(); } } abstract class Iterator //迭代器抽象類別 { public abstract object First(); public abstract object Next(); public abstract bool IsDone(); public abstract object CurrentItem(); } abstract class Aggregate //聚集抽象類別 { public abstract Iterator CreateIterator(); //建立迭代器 } class ConcreteIterator : Iterator //具體的迭代器類——售票員,從頭到尾 { private ConcreteAggregate aggregate; private int current = 0; public ConcreteIterator(ConcreteAggregate aggregate) { this.aggregate = aggregate; } public override object First() { return aggregate[0]; } public override object Next() { object ret = null; current++; if (current < aggregate.Count) { ret = aggregate[current]; } return ret; } public override bool IsDone() { return current >= aggregate.Count ? true : false; } public override object CurrentItem() { return aggregate[current ]; } } class ConcreteAggregate:Aggregate //具體的聚集類——公交車上所有的人 { private IList<object >items=new List<object >(); public override Iterator CreateIterator() { return new ConcreteIterator(this); } public int Count { get{return items.Count ;} } public object this[int index] { get{return items[index ];} set{items.Insert(index,value );} } } //可以使用多種方式遍曆的迭代器模式 class ConcreteIteratorDesc : Iterator //從後向前 { private ConcreteAggregate aggregate; private int current = 0; public ConcreteIteratorDesc(ConcreteAggregate aggregate) { this.aggregate = aggregate; current = aggregate.Count - 1; } public override object First() { return aggregate[aggregate.Count - 1]; } public override object Next() { object ret = null; current--; if (current >= 0) { ret = aggregate[current]; } return ret; } public override bool IsDone() { return current < 0 ? true : false; } public override object CurrentItem() { return aggregate[current ]; } }}