界面開發中,經常使用觀察者設計模式來實現文檔/視圖模式,當文檔內容改變時,作為觀察者的用戶視圖必須相應作出調整以向用戶呈現文檔的狀態。由于語言機制的不同,觀察者設計模式在不同的語言中實現方法也不盡相同。
在MFC的文檔/視圖模式中,每當文檔內容改變都需要調用UpdateAllView函數來更新視圖,該函數會遍歷文檔的每一個視圖,調用每個視圖的更新函數來更新視圖,為此文檔須登記每一個使用該文檔的視圖。C#中觀察者設計模式的實現也可以采用這種方法,但C#提供的代理(delegate)機制為實現觀察者模式提供了更好的方法,該方法和MFC中的方法類似 ,只不過將視圖向文檔注冊這一行為改變為為文檔類的代理生成實例而已,下面看具體實現方法。
先做如下假定:
1、文檔類為UserData;
2、視圖類為View,實際應用中該View可能是一個Form,也可能是一個UserControl,可能有多個視圖,但每一個和文檔的對應方式都是相同的;
3、主窗體為MainForm;
參與觀察者模式的三方分別為:發布者(數據/文檔類)、訂閱者(視圖類)以及主窗體(MainForm),下面分別介紹各方如何實施以配合觀察者模式的實現!
發布者:
發布者的任務是定義數據并在數據改變時通知訂閱者。通知的實現可以使用普通代理,也可以使用事件,首先在UserData中創建代理和事件,每一個事件在UserData類相應屬性改變時觸發,看下面的代碼:
訂閱者:
訂閱者的任務是響應發布者發布的數據改變通知,呈現給用戶實時(相對來說)的系統狀態。
看下面的代碼:
主窗體:
主窗體的任務是定義一個相當于全局的數據對象,將其賦予每個訂閱該對象的視圖,并在需要的時候改變數據對象內容。
看下面的代碼:
private void MainForm_Load(object sender, EventArgs e)
{
m_userData = new UserData(); //生成實例
m_view = new View();
m_view.UserDataObj = m_userData; //為訂閱者指定發布者
m_view.Show(); //顯示
m_userData.UserName = "ZPY"; //改變發布者數據
m_view.TopMost = true;
}
小結
MFC為開發者搭好了框架,盡管作了許多的開發,可能很多人還是不太了解什么是所謂的觀察者模式,C#提供了全開放的設計,可能辛苦些,但不再摸不著頭腦,條理感覺更清晰些,封裝性感覺也比MFC好些!
學習模式注重精髓而非模板,本文為了便于說明假定了三方并對三方功能進行了劃分,實際應用并不拘泥于此。如果情況合適將數據(文檔)類設計為單件模式也是一種很不錯的選擇!總之一句話:掌握精髓,盡情發揮!
新聞熱點
疑難解答