發布者和訂閱者
很多程序都有一個共同的需求,即當一個特定的程序事件發生時,程序的其他部分可以得到
該事件已經發生的通知。
發布者/訂閱者模式(publisher/subscriber pattem)可以滿足這種需求。在這種模式中,發布
者類定義了一系列程序的其他部分可能感興趣的事件。其他類可以“注冊",以便在這些事件發
生時收到發布者的通知。這些訂閱者類通過向發布者提供一個方法來“注冊"以獲取通知。當事
件發生時,發布者“觸發事件",然后執行訂閱者提交的所有事件。
由訂閱者提供的方法稱為回調方法,因為發布者通過執行這些方法來“往回調用訂閱者的方
法”。還可以將它們稱為事件處理程序,因為它們是為處理事件而調用的代碼。圖15-1演示了這
個過程,展示了擁有一個事件的發布者以及該事件的三個訂閱者。
下面是一些有關事件的重要事項。
- 發布者(publisher)發布某個事件的類或結構,其他類可以在該事件發生時得到通知。
- 訂閱者(subscriber)注冊并在事件發生時得到通知的類或結構。
- 事件處理程序(event)由訂閱者注冊到事件的方法,在發布者觸發事件時執行。
事件處理程序方法可以定義在事件所在的類或結構中,也可以定義在不同的類或結構中。 - 觸發(raise)事件調用(invoke)或觸發(fire)事件的術語。當事件被觸發時,所有
注冊到它的方法都會被依次調用。
上一章介紹了委托。事件的很多部分都與委托類似。實際上,事件就像是專門用于某種特殊
用途的簡單委托。委托和事件的行為之所以相似,是有充分理由的。事件包含了一個私有的委托,
如圖15-2所示。
有關事件的私有委托需要了解的重要事項如下。
- 事件提供了對它的私有控制委托的結構化訪問。也就是說,你無法直接訪問委托。
- 事件中可用的操作比委托要少,對于事件我們只可以添加、刪除或調用事件處理程序。
- 事件被觸發時,它調用委托來依次調用調用列表中的方法。
注意,在圖15-2中,只有+=和-=運算符在事件框的左邊。這是因為它們是事件唯一允許的
操作(除了調用事件本身)。
圖15-3演示了一個叫作lncrementer的類,它按照某種方式進行計數。 - lncrementer定義了一個CountedADozen事件,每次累積到12個項時將會觸發該事件。
- 訂閱者類Dozens和SomeOtherClass各有一個注冊到CountedADozen事件的事件處理程序。
- 每當觸發事件時,都會調用這些處理程序。