在軟體建構過程中,我們需要為某些對象建立一種“通知依賴關系” ——一個對象(目标對象)的狀态發生改變,所有的依賴對 象(觀察者對象)都将得到通知。如果這樣的依賴關系過于緊密,将使軟體不能很好地抵禦變化。
使用面向對象技術,可以将這種依賴關系弱化,并形成一種穩定的依賴關系。進而實作軟體體系結構的松耦合。
定義對象間的一種一對多(變化)的依賴關系,以便當一個對象(Subject)的狀态發生改變時,所有依賴于它的對象都得到通知并自動更新。 ——《 設計模式》 GoF
在以前電腦和存儲媒體容量都很小的時候,會經常使用到檔案分割器這種軟體。舉個例子,一部電影400M,隻有一個U盤,64M的,要把它複制到另一台電腦,一次無法完成。就用檔案分割器把400M分成幾塊,每塊約60M,複制到之後,再它分割器把它合成原來的檔案。我們如果想要看到檔案分割器的進度,可以增加一個進度條功能,這個功能的實作也非常的簡單,無非是大檔案分批次向小檔案寫的時候記錄一下,我們通常會寫出下面的代碼:
但這種設計不是很好,依賴實作細節,違背了設計原則的依賴倒置原則,高層子產品不應該依賴于低層子產品,二者都應該依賴于抽象。
Windows、Linux、 控制台下的進度條是不同的,我想讓這個程式都能适應,顯然要設計更多的具體通知控件,僅僅增加了新的通知控件,就需要對原有的FileSplitter類進行修改,這樣的設計是很糟糕的。可以做進一步的抽象,既然有多個通知控件,就可以為這些控件之間抽象一個接口出來,用來取消FileSplitter和具體控件之間的依賴,于是有了觀察者模式。
使用面向對象的抽象,Observer模式使得我們可以獨立地改變目标與觀察者,進而使二者之間的依賴關系達緻松耦合。
目标發送通知時,無需指定觀察者,通知(可以攜帶通知資訊作為參數)會自動傳播。
觀察者自己決定是否需要訂閱通知,目标對象對此一無所知。
Observer模式是基于事件的UI架構中非常常用的設計模式,也是MVC模式的一個重要組成部分。