1. 程式人生 > >設計模式(九)-觀察者模式、C#委託、事件

設計模式(九)-觀察者模式、C#委託、事件

書中引出的例子為,當Boss回來,前臺通知員工好好工作的場景。

1、觀察模式將通知廣播給每一個客戶端,客戶端想知道目標的變化a、從目標拉取 b、通知的時候將變化傳遞給客戶端。

拉取的方法,客戶端自由度較高,客戶端可以根據需求拉取。觀察者通知內容豐富,客戶端需要不要更新拉取變化。耦合度高,違背迪米特法則,推送的方法,效率低,客戶端需要判斷通知型別,耦合度一樣高。

如果收到通知,兩者之間需要來回事務往來,就更糟糕了。

觀察者模式,單向廣播通知,且不需回覆的情景。

書中結尾:委託,的使用更好。從編碼的角度,委託的客戶端更新事件的函式名稱具體清晰,遠比繼承過載的統一介面要好很多。所以下面我們直接講委託。

這裡介紹一片小白初步看懂委託、事件的部落格(C#盲) 

C#委託和事件

這裡抄一些關於委託理解關鍵的語句:

1、(書)委託就是一種引用方法的型別。一旦為委託分配了方法,委託將與該方法具有完全相同的行為。委託方法的使用可以像其他任何方法一樣,具有引數和返回值。委託可以看做是對函式的抽象,是函式的“類”,委託的例項將代表一個具體的函式。

delegate void EventHandler() ----- 宣告一個特殊的類

public event EventHandler Update ---- 宣告一個特殊類的變數-Update

一個委託可以搭載多個方法,所有方法一次執行。委託的方法,不需要屬於同一個類但必須具有相同的原型和形式--必須時相同的引數列表和返回值。

那麼給Update賦值的方式有幾種:

       static void Main() {
           Heater heater = new Heater();
           Alarm alarm = new Alarm();

           heater.BoilEvent += alarm.MakeAlert;    //註冊方法
           heater.BoilEvent += (new Alarm()).MakeAlert;   //給匿名物件註冊方法
           heater.BoilEvent += Display.ShowMsg;       //註冊靜態方法

           heater.BoilWater();   //燒水,會自動呼叫註冊過物件的方法
       }

注意第一種和第二種的區別。兩者執行時的函式地址一樣,但執行結果不一定一樣哦。。。可以查閱一下相關的類的編譯及執行流程。

經常使用函式指標的朋友,可以自己編寫一個委託了。 而C#在遇到 delegate 關鍵字的時候自動幫你把這裡生成一個類,自帶了註冊以及取消註冊的函式(+= , -=),(是不是發現每一個開發平臺都有一些,自己的特性,Qt的 signal、slots、Q_OBJECT關鍵字 )。

委託:C#利用觀察者模式,幫使用者做了充分的結耦合操作。使用者在觀察者與被觀察者之間隨意宣告委託,然後相互繫結,都是很隨意的事情。

某種程度上來講,這個功能在Qt的訊號與曹有一點相似之處,就是兩個完全不相干類的函式的聯絡。Qt5.3之前的版本,連結的函式必須時slots宣告的函式(委託沒有這個限制,三種不同的註冊方法),Qt5.5之後的版本,可用通過lamdba來解決這個問題。

只是要連線多個槽函式時,需要編寫多個connect函式。二委託的+= 更方便(大哭)