天天看點

Java設計模式--觀察者模式觀察者模式(别名:依賴,釋出-訂閱)Observer Pattern(Another Name: Dependents, Publish-Subscribe)類圖模式的結構與使用簡單的例子(推資料)觀察者模式中的“推”資料與“拉”資料簡單的例子(拉資料)觀察者與多主體觀察者模式的優點适用觀察者模式的情景下載下傳源碼請到

定義對象間的一種一對多的依賴關系,當一個對象的狀态發生變化時,所有依賴它的對象都得到通知并被自動更新。

define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

Java設計模式--觀察者模式觀察者模式(别名:依賴,釋出-訂閱)Observer Pattern(Another Name: Dependents, Publish-Subscribe)類圖模式的結構與使用簡單的例子(推資料)觀察者模式中的“推”資料與“拉”資料簡單的例子(拉資料)觀察者與多主體觀察者模式的優點适用觀察者模式的情景下載下傳源碼請到

觀察者模式的結構中包括四個角色。

+ 主題(subject):主題是一個接口,該接口規定了具體主題需要實作的方法,比如,添加、删除觀察者以及通知觀察者更新資料的方法。

+ 具體主題(concrete subject):具體主題是實作主題接口類的一個執行個體,該執行個體包含有可以經常發生變化的資料。具體主題需使用一個集合,比如arraylist,存放觀察者的引用,以便資料變化時通知具體觀察者。

+ 觀察者(observer):觀察者一個接口或者抽象類,該接口規定了具體觀察者用來更新資料的方法。

+ 具體觀察者(concrete observer):具體觀察者是實作觀察者接口類的一個執行個體。具體觀察者包含有可以存放具體主題引用的主題接口變量,以便具體觀察者讓具體主題将自己的引用添加到具體主題中,使自己成為它的觀察者,或讓這個具體主題将自己從具體主題的集合中删除,使自己不再是它的觀察者。

推資料方式是指具體主題将變化後的資料全部交給具體觀察者,即将變化後的資料傳給具體觀察者用于更新資料方法的參數。當具體主題認為具體觀察者需要這些變化後的全部資料時往往采用推資料方式。

拉資料方式是指具體主題不将變化後的資料交給具體觀察者,而是提供了獲得這些資料的方法,具體觀察者在得到通知後,可以調用具體主題提供的方法得到資料(觀察者自己資料“拉”過來),但需要自己判斷資料是否發生變化。當具體主題不知道具體觀察者是需要這些變換後的資料時往往采用拉資料的方式。

一個具體觀察者可以依賴于多個主題,當所有依賴的任何具體主題的資料發生變化時,該觀察者都能得到通知。多主題所涉及的主要問題是觀察者如何處理主題中變化後的資料,因為,不同的具體主題所包含有的資料結構可能很大不同。

在處理多主題時,主題應當采用拉資料方式,觀察者接口可以将更新資料方法的參數類型設定為主題接口類型,比如update(subject subject),即具體主題資料放生變化時将自己的引用傳遞給具體的觀察者,然後具體觀察者讓這個具體主題調用有關的方法傳回該具體主題中的資料。

具體主題和具體觀察者是松耦合關系。由于主題接口僅僅依賴于觀察者接口,是以具體主題隻是知道它的觀察者是實作觀察者接口的某個類的執行個體,但不需要知道具體哪個類。同樣,由于觀察者僅僅依賴于主題接口,是以具體觀察者隻是知道它依賴的主題是實作主題接口的某個類的執行個體,但不需要知道具體是哪一個類。

觀察模式滿足“開-閉原則”。主題接口僅僅依賴于觀察者接口,這樣,就可以讓建立具體主題的類也僅僅是依賴于觀察者接口,是以如果增加新的實作觀察者接口的類,不必修改建立具體主題的類的代碼。同樣,建立具體觀察者的類僅僅依賴于主題接口,如果增加新的實作主題接口的類,也不必修改建立具體觀察者類的代碼。

當一個對象的資料更新時需要通過其他對象,但這個對象又不希望和被通知的那些對象形成緊耦合。

當一個對象的資料更新時,這個對象需要讓其他對象也各自更新自己的資料,但這個對象不知道具體有多少對象需要更新資料。

<a href="https://github.com/androidwolf">mygithub</a>