從前,有個放羊娃,每天都去山上放羊,一天,他覺得十分無聊,就想了個捉弄大家尋開心的主意。他向著山下正在種田的農夫們大聲喊:“狼來了!狼來了!救命啊!”農夫們聽到喊聲急忙拿著鋤頭和鐮刀往山上跑,他們邊跑喊:“不要怕,孩子,我們來幫你打惡狼!”農夫們氣喘吁吁地趕到山上一看,連狼的影子也沒有!放羊娃哈哈大笑:“真有意思,你們上當了!”農夫們生氣地走了。第二天,放羊娃故伎重演,善良的農夫們又沖上來幫他打狼,可還是沒有見到狼的影子。放羊娃笑得直不起腰:“哈哈!你們又上當了!哈哈!”大伙兒對放羊娃一而再再而三地說謊十分生氣,從此再也不相信他的話了。
過了幾天,狼真的來了,一下子闖進了羊群。放羊娃害怕極了,拼命地向農夫們喊:“狼來了!狼來了!快救命呀!狼真的來了!”農夫們聽到他的喊聲,以為他又在說謊,大家都不理睬他,沒有人去幫他,結果放羊娃的許多羊都被狼咬死了。小時候總是纏著爸爸給我講故事,爸爸不厭其煩的講著,我樂呵呵的聽著,就這樣我童年的生活在爸爸多姿多彩的故事中度過,當年聽這個故事,只有一個感悟,做人要誠實,然而今天我換了一個角度看這個故事,搖身一變,她就成了我的設計模式--觀察者模式。
所謂的觀察者模式,將復雜對象的創建與表示分離,使得同樣的構建過程可以創建不同的表示。定義有點抽象,說白了就是:同一個對象,同樣的操作流程,不同的操作細節,可以表現出不同的外觀。首先來看一下我們觀察者模式的結構圖:
? ? ? ??
依然以上述狼來了的故事為例,看看這個故事究竟是怎樣在我們的編程中實現呢?簡單概括上述的故事就是,狼來了,放羊娃通知,農夫放下手頭工作趕來救羊:
~~~
using?System;??
using?System.Collections.Generic;??
using?System.Text;??
??
namespace?觀察者模式??
{??
????class?Program??
????{??
????????static?void?Main(string[]?args)??
????????{??
????????????//狼來了??
????????????Wolf?wolf?=?new?Wolf();??
??
????????????//鋤草的農夫??
?????????????WeedingObserver?Farmer1?=?new?WeedingObserver();??
????????????//澆水的農夫??
????????????WateringObserver?Farmer2?=?new?WateringObserver();??
??
????????????wolf.Update?+=?new?EventHandler(farmer1.StopWeeding);??
????????????wolf.Update?+=?new?EventHandler(farmer2.StopWatering);??
??
????????????//狼來了??
????????????wolf.SubjectState?=?"狼來了!";??
????????????//發出通知??
????????????wolf.Notify();??
??
????????????Console.Read();??
??
??
????????}??
????}??
??
????//通知者接口??
????interface?Subject??
????{??
????????void?Notify();??
????????string?SubjectState??
????????{??
????????????get;??
????????????set;??
????????}??
????}??
??
????//事件處理程序的委托??
????delegate?void?EventHandler();??
??
????class?Shepherd:?Subject??
????{??
????????//聲明一事件Update,類型為委托EventHandler??
????????public?event?EventHandler?Update;??
??
????????private?string?action;??
??
????????public?void?Notify()??
????????{??
????????????Update();??
????????}??
????????public?string?SubjectState??
????????{??
????????????get?{?return?action;?}??
????????????set?{?action?=?value;?}??
????????}??
????}??
??
????class?Wolf:?Subject??
????{??
????????//聲明一事件Update,類型為委托EventHandler??
????????public?event?EventHandler?Update;??
??
????????private?string?action;??
??
????????public?void?Notify()??
????????{??
????????????Update();??
????????}??
????????public?string?SubjectState??
????????{??
????????????get?{?return?action;?}??
????????????set?{?action?=?value;?}??
????????}??
????}??
??
????//鋤草的農夫??
????class??WeedingObserver??
????{??
????????private?string?name;??
????????private?Subject?sub;??
????????public??WeedingObserver(string?name,?Subject?sub)??
????????{??
????????????this.name?=?name;??
????????????this.sub?=?sub;??
????????}??
??
????????//停止鋤草工作??
????????public?void?StopWeeding()??
????????{??
????????????Console.WriteLine("{0}?{1}?停止鋤草工作,趕去救羊!",?sub.SubjectState,?name);??
????????}??
????}??
??
????//澆水的農夫??
????class?WateringObserver??
????{??
????????private?string?name;??
????????private?Subject?sub;??
????????public?WateringObserver(string?name,?Subject?sub)??
????????{??
????????????this.name?=?name;??
????????????this.sub?=?sub;??
????????}??
??
????????//停止澆水??
????????public?void?StopWatering()??
????????{??
????????????Console.WriteLine("{0}?{1}?停止澆水工作,趕去救羊!",?sub.SubjectState,?name);??
????????}??
????}??
}??
~~~
觀察者模式:定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主體對象,這個主題對象在狀態發生變化時,會通知所有觀察者。當一個對象改變需要同時改變其他對象,而且他不知道具體有多少對象需要改變的時候,考慮使用觀察者模式。設計之旅,未完待續......