慢慢的作記錄,作最強大的本身面試
看了大話設計模式以後感觸很深,發現本身還有不少學習的東西,設計軟件並非一兩句代碼把功能寫完了就行,須要思考的內容有不少設計模式
代碼來源參考大話設計模式這本書,這裏在博客裏記錄一下,不可能每次都去翻書,可是在博客裏面是很是好找的。學習
觀察者模式(Observer)算是設計模式裏面最經典的一個模式了,這個模式能夠應用在業務邏輯處理與界面交互的過程當中,官方解釋就是在此種模式中,this
一個目標物件管理全部相依於它的觀察者物件,而且在它自己的狀態改變時主動發出通知。這一般透過呼叫各觀察者所提供的方法來實現。此種模式一般被用來實現事件處理系統。spa
舉一個簡單的例子,以前看到的面試題:設計
貓看見不少老鼠在偷米吃,大叫了一聲,主人醒了,這就是一個經典的觀察者模式,老鼠跟主人都是觀察者(Observer),而貓是一個被觀察者(Subject)code
以前我同事還給我舉了一個例子:項目經理,前臺妹紙,還有科室成員,怎麼防止項目經理忽然間在同事都在作非工做上的事情時,提早預知,那麼就須要前臺妹紙去觀察了。server
那麼怎麼去實現觀察者模式呢,那就是把觀察者當一個總體給抽象出來。對象
就以貓碰見老鼠叫主人被驚醒這個爲例子:blog
首先,理解一下觀察者是誰,這裏面誰跟誰是什麼關係,老鼠碰見貓又是什麼反應,貓叫聲對主人又產生了什麼影響
public interface Observer { void Response(); //觀察者的響應,如是老鼠見到貓的反映 } public interface Subject { void AimAt(Observer obs); //針對哪些觀察者,這裏指貓的要撲捉的對象---老鼠,還有貓驚醒的主人 }
老鼠見到貓的反應用一個類寫出來
public class Mouse : Observer { private string name; public Mouse(string name, Subject subj) { this.name = name; subj.AimAt(this); } public void Response() { Console.WriteLine(name + " 開始逃竄!"); } }
而後主人被貓叫聲吵醒,也是一個反應,這裏繼承觀察者
public class Master : Observer { public Master(Subject subj) { subj.AimAt(this); } public void Response() { Console.WriteLine("吵死了!"); } }
貓是被觀察者,主要產生的行爲就是大叫一聲
public class Cat : Subject { private ArrayList observers; public Cat() { this.observers = new ArrayList(); } public void AimAt(Observer obs) { this.observers.Add(obs); } public void Cry() { Console.WriteLine("貓大叫一聲!"); foreach (Observer obs in this.observers) { obs.Response(); } } }
整個過程在客戶端的代碼就是這樣的
class MainClass { static void Main(string[] args) { Cat cat = new Cat(); Mouse mouse1 = new Mouse("mouse1", cat); Mouse mouse2 = new Mouse("mouse2", cat); Master master = new Master(cat); cat.Cry(); } }
固然這裏耦合程度仍是很高,主人跟老鼠的行爲都是高度依賴貓這個抽象的觀察者,怎麼改才能解耦,那麼就須要用到另一種方式:事件委託
這裏聲明瞭一個委託事件
public delegate void SubEventHandler(); public abstract class Subject { public event SubEventHandler SubEvent; protected void FireAway() { if (this.SubEvent != null) this.SubEvent(); } }
貓對被觀察者的影響
class Cat : Subject { public new event SubEventHandler SubEvent; public void Cry() { SubEvent(); Console.WriteLine("貓大叫!"); } }
而後老鼠跟主人都被貓影響,觀察者被被觀察者影響,產生不一樣的反應
interface Observer { void Response(); //觀察者的響應,如是老鼠見到貓的反映 }
老鼠觀察者的響應,產生逃跑反應
class MouseObserver { private string name; public MouseObserver(string name, Subject subj) { this.name = name; } public void Response() { Console.WriteLine(name + " 趕忙逃離!"); } }
主人觀察者的反應,吵死了
class MasterObserver { private string name; public MasterObserver(string name, Subject subj) { this.name = name; } public void Response() { Console.WriteLine(name + ":吵死了!"); } }
而後在交互端反饋出來是這樣的:
static void Main(string[] args) { Cat cat = new Cat(); MouseObserver mouse1 = new MouseObserver("mouse1", cat); MouseObserver mouse2 = new MouseObserver("mouse2", cat); MasterObserver Master = new MasterObserver("主人", cat); cat.SubEvent += new SubEventHandler(mouse1.Response); cat.SubEvent += new SubEventHandler(mouse2.Response); cat.SubEvent += new SubEventHandler(Master.Response); cat.Cry(); Console.ReadLine(); }
查看運行結果以下:
這樣處理過程就在客戶端進行,就不須要依賴抽象觀察者了