我的武林秘籍設計模式之觀察者模式

自從jack的鴨子游戲得到成功之后,jack的好朋友夏流就覺得心里癢癢的,也想做出一番作為來。

所以,今天的主人公就是這位夏流童鞋。夏流是錢塘江觀測站的一名觀測員,需要向人民群眾反饋錢塘江的水位,水溫,風力,及水里的魚量等信息。在這里經常會有許多市民從他這里打聽當日的錢塘江的這些信息,以便于他們了解,好決定是不是要去江邊做點什么。

于是夏流決定做一個系統(tǒng),能夠自動反饋錢塘江的信息給熱心市民。每當錢塘江的相關信息有變化時,會自動發(fā)送到熱心市民手機上,通知他們。

在觀察者模式中,夏流做的這個錢塘江觀測系統(tǒng)便是一個主題(Subject),熱心市民便是一個觀察者(Observer)

我們定義兩個接口Subject和Observer ,因為我們是有格局,有情懷的程序猿,所以一般我們都是要面向接口編程。

在Subject中,我們定義三個方法,添加觀察者,刪除觀察者,通知觀察者。

在Observer中,只要更新主題發(fā)過來的消息就好,所以只有一個更新方法。

然后我們實現具體主題,也就是錢塘江觀測站,在錢塘江觀測站中,水位,水溫,風力,魚的條數都是它的屬性,還有一個是觀察者列表,所有的觀察者都存在這個ObserverList里。當有新的信息更新時,他就調用notifyObserver方法通知他們的觀察者去更新信息。

接著呢是實現觀察者了,這個市民就是具體的觀察者了。觀察者中維護了一個主題,這個主題就是他關注的那個主題,也就是錢塘江觀測站了,它有了這個主題就能夠把自己給添加到這個主題的觀察者列表中了。


夏流按照這個思路設計完了該系統(tǒng),卻遭到了一些熱心市民的抱怨。一位愛釣魚的王大伯說,我只要當天的水位和魚的數量信息,其他信息這么多給我并沒有軟用。

另一位愛游泳的劉叔叔說,我只要水溫很風力信息就夠了,這樣我才能知道我該不該下水游泳(當然在錢塘江游泳釣魚啥的都是非常危險的,這里只是舉個例子)

另一位愛拍照的王阿姨說,我只要風力信息,希望我能借助風力吹起我美麗的秀發(fā),用我的美顏相機定格住那美麗的瞬間

夏流聽到了各位熱心市民的意見,決定改善一下系統(tǒng)。

他想這樣的話,就在通知觀察者的時候,讓update方法不帶參數。反正他們內部已經維護了一個主題,讓他們自己根據自己所需去從這個主題中拿數據就好了。

以下是修改后的類圖


主要還是修改觀察者中的update方法,一個是直接通過update方法一股腦把所有信息傳過來,另一個是通過觀察者自身所維護的主題中去取。

接著有了這個設計,我們好實現代碼了

package qiantang;

/**

* Created by huangx on 2018/11/14.

*/

public interface Observer {

void update();

? ? void display();

}

package qiantang;

/**

* Created by huangx on 2018/11/14.

*/

public interface Subject {

void addObserver(Observer observer);

? ? void deleteObserver(Observer observer);

? ? void notifyObserver();

}

package qiantang;

import java.util.ArrayList;

import java.util.List;

/**

* Created by huangx on 2018/11/14.

*/

public class QiangtangRiverStationimplements Subject {

private int height;

? ? private int tempature;

? ? private int wind;

? ? private int fish;

? ? private ListobserverList =new ArrayList();

? ? public void addObserver(Observer observer) {

observerList.add(observer);

? ? }

public void deleteObserver(Observer observer) {

observerList.remove(observer);

? ? }

public void notifyObserver() {

for (Observer observer :observerList) {

observer.update();

? ? ? ? }

}

public void setNewInfo(int height, int tempature, int wind, int fish) {

this.height = height;

? ? ? ? this.tempature = tempature;

? ? ? ? this.wind = wind;

? ? ? ? this.fish = fish;

? ? ? ? notifyObserver();

? ? }

public int getHeight() {

return height;

? ? }

public int getTempature() {

return tempature;

? ? }

public int getWind() {

return wind;

? ? }

public int getFish() {

return fish;

? ? }

}


package qiantang;

/**

* Created by huangx on 2018/11/14.

*/

public class FishCitizenimplements Observer {

private Stringname;

? ? private int fish;

? ? private int height;

? ? private Subjectsubject;

? ? public FishCitizen(String name, Subject subject) {

this.name = name;

? ? ? ? this.subject = subject;

? ? ? ? subject.addObserver(this);//關鍵一步把自己扔到主題中去

? ? }

public void update() {

if (subject instanceof QiangtangRiverStation) {

this.fish = ((QiangtangRiverStation)subject).getFish();

? ? ? ? ? ? this.height = ((QiangtangRiverStation)subject).getHeight();

? ? ? ? }

display();

? ? }

public void display() {

System.out.println("我是" +name +",今天的魚量是" +fish +",今天 的水位是" +height);

? ? }

}


package qiantang;

/**

* Created by huangx on 2018/11/14.

*/

public class SwimCitizenimplements Observer {

private Stringname;

? ? private int tempature;

? ? private int wind;

? ? private Subjectsubject;

? ? public SwimCitizen(String name, Subject subject) {

this.name = name;

? ? ? ? this.subject = subject;

? ? ? ? subject.addObserver(this);

? ? }

public void update() {

if (subject instanceof QiangtangRiverStation) {

this.tempature = ((QiangtangRiverStation)subject).getTempature();

? ? ? ? ? ? this.wind = ((QiangtangRiverStation)subject).getWind();

? ? ? ? }

display();

? ? }

public void display() {

System.out.println("我是" +name +",今天的溫度是" +tempature +",今天 的風力是" +wind);

? ? }

}


package qiantang;

/**

* Created by huangx on 2018/11/14.

*/

public class PhotoCitizenimplements Observer {

private Stringname;

? ? private int wind;

? ? private Subjectsubject;

? ? public PhotoCitizen(String name, Subject subject) {

this.name = name;

? ? ? ? this.subject = subject;

? ? ? ? subject.addObserver(this);

? ? }

public void update() {

if (subject instanceof QiangtangRiverStation) {

this.wind = ((QiangtangRiverStation)subject).getWind();

? ? ? ? }

display();

? ? }

public void display() {

System.out.println("我是" +name +",今天的風力是" +wind +"今天的我一定是個小公舉");

? ? }

}

package qiantang;

/**

* Created by huangx on 2018/11/14.

*/

public class TestApplication {

public static void main(String[] args) {

QiangtangRiverStation qiangtangRiverStation=new QiangtangRiverStation();

? ? ? ? SwimCitizen swimCitizen=new SwimCitizen("劉叔叔",qiangtangRiverStation);

? ? ? ? FishCitizen fishCitizen=new FishCitizen("王大伯",qiangtangRiverStation);

? ? ? ? PhotoCitizen photoCitizen=new PhotoCitizen("王阿姨",qiangtangRiverStation);

? ? ? ? qiangtangRiverStation.setNewInfo(11,22,33,44);

? ? ? ? qiangtangRiverStation.setNewInfo(55,66,77,88);

? ? }

}

運行結果:

有了這個設計,夏流童鞋不僅受到了大伯大媽的好評,也幫助他成為杭州杰出青年的好榜樣。

觀察者模式的官方定義是:定義對象見的一種一對多的依賴關系,當一個對象的狀態(tài)發(fā)送變化時,所有依賴它的對象都得到通知并被自動更新。

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 設計模式分類 總體來說設計模式分為三大類:創(chuàng)建型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原...
    lifeline丿毅閱讀 1,362評論 0 2
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現,斷路器,智...
    卡卡羅2017閱讀 136,724評論 19 139
  • 今晚一次全新體驗,雖跟不上節(jié)奏,雖有點不適應,但為了你,我們會記得用一種新的方式云詮釋,等待是新的際遇!
    子之霧閱讀 302評論 0 0
  • 騎天大勝 焦點少年班堅持分享第348天 星期二 2018.6.26 其實那一次涂色我也是不太用功,因為畢竟我已經完...
    她說夢里花會開閱讀 184評論 0 0
  • 姥爺的走對我來說不算突然,周二晚上媽媽打電話告訴我姥爺胃出血打了120住院,我說如果很嚴重我就請假回去,不...
    愛藍天的妞兒閱讀 740評論 1 3

友情鏈接更多精彩內容