行為型模式: 策略模式 它定義了算法家族,分別封裝起來,讓它們之間可以相互替換,此模式讓算法的變化,不會影響到使用算法的客戶。 簡單工廠模式的不足: 由於工廠本身包括了所有的收費方式,商場是可能經常性的更改打折額度和返利額度,每次維護或擴展收費方法都要改動這個工廠,以致代碼需重新編譯部署,很麻煩 方法: 1,定義一個所有支持的算法的公共接口 2,將所有具體算法或行為封裝在一起 3,維護對公共接口的引用 客戶端代碼是將所有的算法實例化 這個模式涉及到三個角色: 環境(Context)角色:持有一個Strategy類的引用。 抽象策略(Strategy)角色:這是一個抽象角色,通常由一個接口或抽象類實現。此角色給出所有的具體策略類所需的接口。 具體策略(ConcreteStrategy)角色:包裝了相關的算法或行為 優點: 使用策略模式可以把行為和環境分割開來。環境類負責維持和查詢行為類,各種算法則在具體策略類(ConcreteStrategy)中提供。由於算法和環境獨立開來,算法的增減、修改都不會影響環境和客戶端。當出現新的促銷折扣或現有的折扣政策出現變化時,只需要實現新的策略類,並在客戶端登記即可。策略模式相當於"可插入式(Pluggable)的算法" 個人理解: 策略模式與工廠模式 工廠模式是將需要實例化的所有對象放到一個類中,然後在客戶端直接使用工廠的方法,實現不同對象的不同操作 策略模式是將工廠中的方法提取出來,然後將需要實例化的對象都放到了客戶端去實例。當我需要添加不同的策略時,只在客戶端添加它的實例即可,然後將對象作為參數傳到策略模式中即可 策略模式結構圖: 課本實例:商場打折 代碼如下: [csharp] class cashcontext { //基類類型的對像 private CashSuper cs; //初始化時(構造函數),傳入具體的對象 public cashcontext(CashSuper csuper) { this.cs = csuper; //將csuper賦給cs,然後計算cs對象的收到的現金數 //通過傳入參數的不同,計算不同方式的收到現金數 } public double getresult(double money) //根據具體的策略對象,調用其算法的方法 { return cs.acceptCash(money); } } 備忘錄模式 在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態.這樣以後就可將該對象恢復到原先保存的狀態. Memento模式比較適用於功能比較 復雜的,但需要維護或記錄屬性歷史的類,或者需要保存的屬性只是眾多屬性中的一小部分時,Originator可以根據保存的Memento信息還原到前一狀態 課本實例:游戲的狀態保存 代碼如下: [csharp] //一個發起人類:有攻擊力,生命力,還有創建備忘和恢復備忘的功能等 class GameRole { //生命力 private int vit; public int Vitality { get { return vit; } set { vit = value; } } //攻擊力 private int atk; public int Attack { get { return atk ; } set { atk = value; } } //防御類 private int def; public int Defense { get { return def ; } set { def = value; } } //狀態顯示 public void StateDisplay() { Console.WriteLine("角色當前狀態:"); Console.WriteLine("體力:{0}", this.vit); Console.WriteLine("攻擊力:{0}", this.atk); Console.WriteLine("防御類:{0}", this.def); Console.WriteLine(""); } //獲得初始狀態 public void GetInitState() { this.vit = 100; this.atk = 100; this.def = 100; } //戰斗 public void Fight() { this.vit = 0; this.atk = 0; this.def = 0; } //保存角色狀態 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; } } } //客戶端: //大戰前 GameRole hejingyuan = new GameRole(); hejingyuan.GetInitState(); hejingyuan.StateDisplay(); //保存進度 RoleStateCaretaker stateAdmin = new RoleStateCaretaker(); stateAdmin.Memento = hejingyuan.SaveState(); //大戰時,損耗嚴重 hejingyuan.Fight(); hejingyuan.StateDisplay(); //恢復之前狀態 hejingyuan.RecoveryState(stateAdmin.Memento); hejingyuan.StateDisplay(); Console.Read(); 個人理解: 備忘錄模式:當我要保存備忘時,再發起人(游戲角色)這個類中就創建備忘錄,備忘錄這個類中具有要備忘的一些內容(屬性和方法)等,管理者是對備忘錄進行包裝,在客戶端將發起人備忘賦給管理者這個對象,這樣客戶端的人就不需要知道我備忘的是什麼內容了。 迭代器模式 提供一種方法順序訪問一個聚合對象中各個元素,而又不暴露該對象的內部表示。 當你需要訪問一個聚集對象,而且不管這些對象是什麼都需要遍歷的時候,你就應該考慮用迭代器模式 應用: 當你需要對聚集有多種方法遍歷時,可以考慮用迭代器模式 總的來說,迭代器模式就是分離了集合對象的遍歷行為,抽象出一個迭代器類來負責,這樣既可以做到不暴露集合的內部結構,又可讓外部代碼透明地訪問集合內部的數據. 課本實例:乘車買票 代碼如下: [csharp] //Iterator迭代器抽象類 abstract class Iterator { public abstract object First(); public abstract object Next(); public abstract object IsDone(); public abstract object CurrentItem(); } //迭代器就是對一個聚集對象遍歷 //ConcreteIterator具體迭代器類,繼承Iterator 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 object IsDone() { return current >= aggregate.Count ? true : false; } public override object CurrentItem() { return aggregate[current]; } } //具體迭代器就是對具體聚集對象的操作,也是對抽象迭代器的重寫 //Aggregate abstract class Aggregate { public abstract Iterator CreateIterator(); } //抽象聚集類就是要創建迭代器 //ConcreteAggregate具體聚集類 繼承Aggregate 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); } } } //具體聚集類中有用於存放聚合對象的變量,對抽象聚集類重寫,還有聚集總數,和聲明一個索引器