Java中的观察者设计模式-示例教程
觀察者模式是行為設(shè)計(jì)模式之一 。 當(dāng)您對(duì)對(duì)象的狀態(tài)感興趣并希望在發(fā)生任何更改時(shí)得到通知時(shí),觀察者設(shè)計(jì)模式很有用。 在觀察者模式中,監(jiān)視另一個(gè)對(duì)象狀態(tài)的對(duì)象稱為Observer ,而正在監(jiān)視的對(duì)象稱為Subject 。 根據(jù)GoF,觀察者模式意圖是:
在對(duì)象之間定義一對(duì)多依賴關(guān)系,以便當(dāng)一個(gè)對(duì)象更改狀態(tài)時(shí),將自動(dòng)通知和更新其所有依賴關(guān)系。
主題包含觀察者列表,以通知其狀態(tài)的任何變化,因此它應(yīng)提供觀察者可以自己注冊(cè)和注銷的方法。 主題還包含一種將所有更改通知所有觀察者的方法,它既可以在通知觀察者的同時(shí)發(fā)送更新,也可以提供另一種獲取更新的方法。
觀察者應(yīng)該有一個(gè)方法來設(shè)置要監(jiān)視的對(duì)象,另一種方法將由Subject用來通知他們?nèi)魏胃隆?
Java提供了一個(gè)內(nèi)置平臺(tái),用于通過java.util.Observable類和java.util.Observer接口實(shí)現(xiàn)Observer模式。 但是由于它的實(shí)現(xiàn)非常簡(jiǎn)單,因此并未得到廣泛使用,并且大多數(shù)時(shí)候我們不想只為了實(shí)現(xiàn)Observer模式而擴(kuò)展一個(gè)類,因?yàn)镴ava在類中不提供多重繼承。
Java消息服務(wù)(JMS)使用Observer模式和Mediator模式來允許應(yīng)用程序?qū)?shù)據(jù)訂閱和發(fā)布到其他應(yīng)用程序。
模型-視圖-控制器(MVC)框架還使用觀察者模式,其中模型是主題,視圖是觀察者,可以注冊(cè)以獲取有關(guān)模型的任何更改的通知。
觀察者模式示例
對(duì)于我們的示例,我們將實(shí)現(xiàn)一個(gè)簡(jiǎn)單的主題,觀察者可以注冊(cè)該主題。 每當(dāng)將任何新消息發(fā)布到該主題時(shí),所有注冊(cè)觀察者都會(huì)收到通知,他們可以使用該消息。
根據(jù)主題的要求,這里是基本主題接口,用于定義任何具體主題要實(shí)施的合同方法。
package com.journaldev.design.observer;public interface Subject {//methods to register and unregister observerspublic void register(Observer obj);public void unregister(Observer obj);//method to notify observers of changepublic void notifyObservers();//method to get updates from subjectpublic Object getUpdate(Observer obj);}接下來,我們將為觀察者創(chuàng)建合同,將有一種方法將Subject附加到觀察者,另一種方法供Subject用來通知任何更改。
package com.journaldev.design.observer;public interface Observer {//method to update the observer, used by subjectpublic void update();//attach with subject to observepublic void setSubject(Subject sub); }現(xiàn)在我們的合同已經(jīng)準(zhǔn)備好了,讓我們繼續(xù)具體執(zhí)行該主題。
package com.journaldev.design.observer;import java.util.ArrayList; import java.util.List;public class MyTopic implements Subject {private List<Observer> observers;private String message;private boolean changed;private final Object MUTEX= new Object();public MyTopic(){this.observers=new ArrayList<>();}@Overridepublic void register(Observer obj) {if(obj == null) throw new NullPointerException("Null Observer");if(!observers.contains(obj)) observers.add(obj);}@Overridepublic void unregister(Observer obj) {observers.remove(obj);}@Overridepublic void notifyObservers() {List<Observer> observersLocal = null;//synchronization is used to make sure any observer registered after message is received is not notifiedsynchronized (MUTEX) {if (!changed)return;observersLocal = new ArrayList<>(this.observers);this.changed=false;}for (Observer obj : observersLocal) {obj.update();}}@Overridepublic Object getUpdate(Observer obj) {return this.message;}//method to post message to the topicpublic void postMessage(String msg){System.out.println("Message Posted to Topic:"+msg);this.message=msg;this.changed=true;notifyObservers();}}注冊(cè)和注銷觀察者的方法實(shí)現(xiàn)非常簡(jiǎn)單,額外的方法是postMessage() ,客戶端應(yīng)用程序?qū)⑹褂迷摲椒▽tring消息發(fā)布到主題。 請(qǐng)注意,布爾變量用于跟蹤主題狀態(tài)的變化,并用于通知觀察者。 此變量是必需的,這樣,如果沒有更新,并且有人調(diào)用notifyObservers()方法,它就不會(huì)向觀察者發(fā)送錯(cuò)誤的通知。
還要注意在notifyObservers()方法中使用了同步 ,以確保僅將消息發(fā)送給在將消息發(fā)布到主題之前注冊(cè)的觀察者。
這是將監(jiān)視該主題的Observers的實(shí)現(xiàn)。
package com.journaldev.design.observer;public class MyTopicSubscriber implements Observer {private String name;private Subject topic;public MyTopicSubscriber(String nm){this.name=nm;}@Overridepublic void update() {String msg = (String) topic.getUpdate(this);if(msg == null){System.out.println(name+":: No new message");}elseSystem.out.println(name+":: Consuming message::"+msg);}@Overridepublic void setSubject(Subject sub) {this.topic=sub;}}請(qǐng)注意update()方法的實(shí)現(xiàn),在此方法中它正在調(diào)用Subject getUpdate()方法來獲取要使用的消息。 我們可以通過將message作為參數(shù)傳遞給update()方法來避免此調(diào)用。
這是使用我們的主題實(shí)現(xiàn)的簡(jiǎn)單測(cè)試程序。
package com.journaldev.design.observer;public class ObserverPatternTest {public static void main(String[] args) {//create subjectMyTopic topic = new MyTopic();//create observersObserver obj1 = new MyTopicSubscriber("Obj1");Observer obj2 = new MyTopicSubscriber("Obj2");Observer obj3 = new MyTopicSubscriber("Obj3");//register observers to the subjecttopic.register(obj1);topic.register(obj2);topic.register(obj3);//attach observer to subjectobj1.setSubject(topic);obj2.setSubject(topic);obj3.setSubject(topic);//check if any update is availableobj1.update();//now send message to subjecttopic.postMessage("New Message");}}當(dāng)我們運(yùn)行上面的程序時(shí),我們得到以下輸出。
Obj1:: No new message Message Posted to Topic:New Message Obj1:: Consuming message::New Message Obj2:: Consuming message::New Message Obj3:: Consuming message::New Message觀察者模式類圖
觀察者模式也稱為發(fā)布-訂閱模式。 它的一些實(shí)現(xiàn)是;
- Swing中的java.util.EventListener
- javax.servlet.http.HttpSessionBindingListener
- javax.servlet.http.HttpSessionAttributeListener
這就是Java中Observer模式的全部?jī)?nèi)容,希望您喜歡它。 通過評(píng)論和與他人分享來分享您的愛。
參考: Java的觀察者設(shè)計(jì)模式- 開發(fā)人員博客上來自我們JCG合作伙伴 Pankaj Kumar的示例教程 。翻譯自: https://www.javacodegeeks.com/2013/08/observer-design-pattern-in-java-example-tutorial.html
總結(jié)
以上是生活随笔為你收集整理的Java中的观察者设计模式-示例教程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蔚来手机新增 16GB+512GB /
- 下一篇: LG 新款 27UQ750 显示器今晚开