Java設計模式補充:回撥模式、事件監聽器模式、觀察者模式(轉)
一、回撥函式
為什麼首先會講回撥函式呢?因為這個是理解監聽器、觀察者模式的關鍵。
什麼是回撥函式
所謂的回撥,用於回撥的函式。 回撥函式只是一個功能片段,由使用者按照回撥函式呼叫約定來實現的一個函式。 有這麼一句通俗的定義:就是程式設計師A寫了一段程式(程式a),其中預留有回撥函式介面,並封裝好了該程式。程式設計師B要讓a呼叫自己的程式b中的一個方法,於是,他通過a中的介面回撥自己b中的方法。
舉個例子:
這裡有兩個實體:回撥抽象介面、回撥者(即程式a)
回撥介面(ICallBack )
public interface ICallBack { public void callBack(); }
回撥者(用於呼叫回撥函式的類)
public class Caller { public void call(ICallBack callBack){ System.out.println("start..."); callBack.callBack(); System.out.println("end..."); } }
回撥測試:
public static void main(String[] args) { Caller call = new Caller(); call.call(new ICallBack(){ @Overridepublic void callBack() { System.out.println("終於回撥成功了!"); } }); }
控制檯輸出:
start...
終於回撥成功了!
end...
還有一種寫法
ICallBack callBackB = new ICallBack(){ @Override public void callBack() { System.out.println("終於回撥成功了!"); } }; call.call(callBackB);
或實現這個ICallBack介面類
class CallBackC implements ICallBack{ @Override public void callBack() { System.out.println("終於回撥成功了!"); } }
有沒有發現這個模型和執行一個執行緒,Thread很像。 沒錯,Thread就是回撥者,Runnable就是一個回撥介面。
new Thread(new Runnable(){ @Override public void run() { System.out.println("回撥一個新執行緒!"); }}).start();
Callable也是一個回撥介面,原來一直在用。 接下來我們開始講事件監聽器
二、事件監聽模式
什麼是事件監聽器
監聽器將監聽自己感興趣的事件一旦該事件被觸發或改變,立即得到通知,做出響應。例如:Android程式中的Button事件。
Java的事件監聽機制可概括為3點:
- Java的事件監聽機制涉及到事件源,事件監聽器,事件物件三個元件,監聽器一般是介面,用來約定呼叫方式。
- 當事件源物件上發生操作時,它將會呼叫事件監聽器的一個方法,並在呼叫該方法時傳遞事件物件過去。
- 事件監聽器實現類,通常是由開發人員編寫,開發人員通過事件物件拿到事件源,從而對事件源上的操作進行處理。
舉個例子
這裡我為了方便,直接使用JDK,EventListener 監聽器,感興趣的可以去研究下原始碼,非常簡單。
監聽器介面
public interface EventListener extends java.util.EventListener { //事件處理 public void handleEvent(EventObject event); }
事件物件
public class EventObject extends java.util.EventObject{ private static final long serialVersionUID = 1L; public EventObject(Object source){ super(source); } public void doEvent(){ System.out.println("通知一個事件源 source :"+ this.getSource()); } }
事件源
事件源是事件物件的入口,包含監聽器的註冊、撤銷、通知
public class EventSource { //監聽器列表,監聽器的註冊則加入此列表 private Vector<EventListener> ListenerList = new Vector<EventListener>(); //註冊監聽器 public void addListener(EventListener eventListener){ ListenerList.add(eventListener); } //撤銷註冊 public void removeListener(EventListener eventListener){ ListenerList.remove(eventListener); } //接受外部事件 public void notifyListenerEvents(EventObject event){ for(EventListener eventListener:ListenerList){ eventListener.handleEvent(event); } } }
測試執行
public static void main(String[] args) { EventSource eventSource = new EventSource(); eventSource.addListener(new EventListener(){ @Override public void handleEvent(EventObject event) { event.doEvent(); if(event.getSource().equals("closeWindows")){ System.out.println("doClose"); } } }); /* * 傳入openWindows事件,通知listener,事件監聽器, 對open事件感興趣的listener將會執行 **/ eventSource.notifyListenerEvents(new EventObject("openWindows")); }
控制檯顯示:
通知一個事件源 source :openWindows
通知一個事件源 source :openWindows
doOpen something...
到這裡你應該非常清楚的瞭解,什麼是事件監聽器模式了吧。 那麼哪裡是回撥介面,哪裡是回撥者,對!EventListener是一個回撥介面類,handleEvent是一個回撥函式介面,通過回撥模型,EventSource 事件源便可回撥具體監聽器動作。
有了瞭解後,這裡還可以做一些變動。 對特定的事件提供特定的關注方法和事件觸發
public class EventSource { ... public void onCloseWindows(EventListener eventListener){ System.out.println("關注關閉視窗事件"); ListenerList.add(eventListener); } public void doCloseWindows(){ this.notifyListenerEvents(new EventObject("closeWindows")); } ... } public static void main(String[] args) { EventSource windows = new EventSource(); /** * 另一種實現方式 */ //關注關閉事件,實現回撥介面 windows.onCloseWindows(new EventListener(){ @Override public void handleEvent(EventObject event) { event.doEvent(); if(event.getSource().equals("closeWindows")){ System.out.println("通過onCloseWindows來關注關閉視窗事件:並執行成功。 closeWindows"); } } }); //視窗關閉動作 windows.doCloseWindows(); }
這種就類似於,我們的視窗程式,Button監聽器了。我們還可以為單擊、雙擊事件定製監聽器。
三、觀察者模式
什麼是觀察者模式
觀察者模式其實原理和監聽器是一樣的,使用的關鍵在搞清楚什麼是觀察者、什麼是被觀察者。
- 觀察者(Observer)相當於事件監器。有個微博模型比較好理解,A使用者關注B使用者,則A是B的觀察者,B是一個被觀察者,一旦B發表任何言論,A便可以獲得。
- 被觀察者(Observable)相當於事件源和事件,執行事件源通知邏輯時,將會回撥observer的回撥方法update。
舉個例子
為了方便,同樣我直接使用JDK自帶的Observer。
一個觀察者
public class WatcherDemo implements Observer { @Override public void update(Observable o, Object arg) { if(arg.toString().equals("openWindows")){ System.out.println("已經開啟視窗"); } } }
被觀察者
Observable是JDK自帶的被觀察者,具體可以自行看原始碼和之前的監聽器事件源類似。
主要方法有:
- addObserver()新增觀察者,與監聽器模式類似。
- notifyObservers()通知所有觀察者。
類Watched.java的實現描述:被觀察者,相當於事件監聽的事件源和事件物件。又理解為訂閱的物件 主要職責:註冊/撤銷觀察者(監聽器),接收主題物件(事件物件)傳遞給觀察者(監聽器),具體由感興趣的觀察者(監聽器)執行
/** * * 類Watched.java的實現描述:被觀察者,相當於事件監聽的事件源和事件物件。又理解為訂閱的物件 * 主要職責:註冊/撤銷觀察者(監聽器),接收主題物件(事件物件)傳遞給觀察者(監聽器),具體由感興趣的觀察者(監聽器)執行 * @author xuan.lx 2016年11月22日 下午3:52:11 */ public class Watched extends Observable { public void notifyObservers(Object arg) { /** * 為避免併發衝突,設定了changed標誌位changed =true,則當前執行緒可以通知所有觀察者,內部同步塊會完了會設定為false; 通知過程中,正在新註冊的和撤銷的無法通知到。 */ super.setChanged(); /** * 事件觸發,通知所有感興趣的觀察者 */ super.notifyObservers(arg); } }
測試執行
public static void main(String[] args) { Watched watched = new Watched(); WatcherDemo watcherDemo = new WatcherDemo(); watched.addObserver(watcherDemo); watched.addObserver(new Observer(){ @Override public void update(Observable o, Object arg) { if(arg.toString().equals("closeWindows")){ System.out.println("已經關閉視窗"); } } }); //觸發開啟視窗事件,通知觀察者 watched.notifyObservers("openWindows"); //觸發關閉視窗事件,通知觀察者 watched.notifyObservers("closeWindows"); }
控制檯輸出:
已經開啟視窗
已經關閉視窗
總結
從整個實現和呼叫過程來看,觀察者和監聽器模式基本一樣。
有興趣的你可以基於這個模型,實現一個簡單微博加關注和取消的功能。 說到底,就是事件驅動模型,將呼叫者和被呼叫者通過一個連結串列、回撥函式來解耦掉,相互獨立。
整個設計模式的初衷也就是要做到低耦合,低依賴。
再延伸下,訊息中介軟體是什麼一個模型?將生產者+服務中心(事件源)和消費者(監聽器)通過訊息佇列解耦掉. 訊息這相當於具體的事件物件,只是儲存在一個佇列裡(有消峰填谷的作用),服務中心回撥消費者介面通過拉或取的模型響應。 想必基於這個模型,實現一個簡單的訊息中介軟體也是可以的。
還比如Guava ListenableFuture,採用監聽器模式就解決了future.get()一直阻塞等待返回結果的問題。
有興趣的同學,可以再思考下觀察者和責任鏈之間的關係, 我是這樣看的。
同樣會存在一個連結串列,被觀察者會通知所有觀察者,觀察者自行處理,觀察者之間互不影響。 而責任鏈,講究的是擊鼓傳花,也就是每一個節點只需記錄繼任節點,由當前節點決定是否往下傳。 常用於工作流,過濾器Web Filter。
相關推薦
Java設計模式補充:回撥模式、事件監聽器模式、觀察者模式(轉)
一、回撥函式為什麼首先會講回撥函式呢?因為這個是理解監聽器、觀察者模式的關鍵。什麼是回撥函式所謂的回撥,用於回撥的函式。 回撥函式只是一個功能片段,由使用者按照回撥函式呼叫約定來實現的一個函式。 有這麼一句通俗的定義:就是程式設計師A寫了一段程式(程式a),其中預留有回撥函式
Java設計模式補充:回調模式、事件監聽器模式、觀察者模式(轉)
應該 hand 關閉 lan china 關註 update 使用 event 一、回調函數 為什麽首先會講回調函數呢?因為這個是理解監聽器、觀察者模式的關鍵。 什麽是回調函數 所謂的回調,用於回調的函數。 回調函數只是一個功能片段,由用戶按照回調函數調用約定來實現的
javaweb監聽器接口-觀察者模式
監聽器javaweb監聽器接口有8個分別是ServletRequestListener,HttpSessionListener,ServletContextListener, ServletRequestAttributeListener,HttpSessionAttributeListener,Servle
事件驅動模型和觀察者模式
你有一件事情,做這件事情的過程包含了許多職責單一的子過程。這樣的情況及其常見。當這些子過程有如下特點時,我們應該考慮設計一種合適的框架,讓框架來完成一些業務無關的事情,從而使得各個子過程的開發可以專注於自己的業務。 這些子過程有一定的執行次序; 這些子過程之間需要較靈活
【C#】Event事件的應用之觀察者模式
using System; namespace Event { // 在遊戲設計中,通常會出現這樣的場景,有一個正在巡邏的敵軍隊伍,當玩家攻擊了其中之一的敵人時 // 那個隊伍的所有敵人都會注意到玩家,並且開始攻擊玩家 // 以下便是個觀察者模式的簡略程式碼
Java中泛型T和Class<T>以及Class<?>的理解(轉)
tcl ota 特定 類型 基本 ext pla enum extend 註意:class是java的關鍵字, 在聲明Java類時使用; Class類的實例表示Java應用運行時的類(class ans enum)或接口(interface and annotatio
DeepMind詳解新WaveNet:比原來快千倍,語音更自然 | 附論文(轉) DeepMind詳解新WaveNet:比原來快千倍,語音更自然 | 附論文
mark一下,感謝作者分享! https://blog.csdn.net/yh0vlde8vg8ep9vge/article/details/78621165 原 DeepMind詳解新WaveNet:比原來快千倍,語音更自然 |
highcharts入門之Pie:如何讓Pie餅狀圖的圖例內顯示百分比(轉)
有很多人都在詢問如何在highcharts的pie 餅狀圖內顯示百分比,通過不斷琢磨最後得出了一個結論,只需要簡單配置即可實現這樣一個需求。 完整核心程式碼如下所示: $(function () { var chart; //
Java設計模式-回撥函式和觀察者模式
Android的框架中有非常多的地方使用了回撥的模式,例如Activity的生命週期,按鈕的點選事件等。 下面是回撥的基本模型: public class A { private CallBack callback; //註冊一個事件 public void reg
Java中的設計模式(七):觀察者模式
name int 還要 The else 意圖 http exceptio 所有 介紹 觀察者模式是行為設計模式之一。當您對對象的狀態感興趣並希望在有任何更改時收到通知時,觀察者設計模式非常有用。在觀察者模式中,監視另一個對象狀態的對象稱為Observer,正在被監視的對象
Java設計模式11:觀察者模式
一、什麼是觀察者模式 在閻巨集博士的《JAVA與模式》一書中開頭是這樣描述觀察者(Observer)模式的: 觀察者模式是物件的行為模式,又叫釋出-訂閱(Publish/Subscribe)模式、模型-檢視(Model/View)模式、源-監聽器(Source/Listener)模式
Java程式效能優化 讀書筆記(六)設計模式:觀察者模式
一、觀察者模式 觀察者模式定義了物件間的一種一對多依賴關係,使得每當一個物件改變狀態,則所有依賴於它的物件都會得到通知並被自動更新。它將觀察者和被觀察者的物件分離開。提高了應用程式的可維護性和重用性。觀察者模式又稱為釋出/訂閱(Publish/Subscribe)模式。 觀
Java設計模式:觀察者模式(Observer Pattern)
觀察者模式:類似於報紙和雜誌的訂閱 出版者+訂閱者=觀察者模式 1.報紙的業務就是出版報紙。 2.向某家報社訂閱報紙,只要他們有新報紙出版,就會給你送來。只要你是他們的訂閱使用者,你就會一直收到新報紙。 3.當你不想再看報紙時,取消訂閱,他們就不會再
Java設計模式:觀察者模式以及Servlet中的Listener
觀察者模式(Observer Pattern)也稱釋出訂閱模式,它是一種在實際開發中經常用到的一種模式。 觀察者模式定義:定義物件一種一對多的依賴關係,使得每當一個物件改變狀態時,則所依賴它的物件會得到通知並被自動更新。 觀察者類圖如下: 圖1 觀察者模式的類圖 觀
Java中的設計模式 - 觀察者模式【又叫:釋出/訂閱模式】
文章目錄 Java中的設計模式 - 觀察者模式【又叫:釋出/訂閱模式】 1、觀察者模式是為了解決什麼問題 2、核心邏輯 3、優點 4、缺點 5、應用場景
Java設計模式六:觀察者模式(Observer)
觀察者模式定義了物件間的一種一對多依賴關係,使得每當一個物件改變狀態,則所有依賴於它的物件都會得到通知並被自動更新。 它將觀察者和被觀察者的物件分離開。提高了應用程式的可維護性和重用性。 實現觀察者模式有很多形式,一種是“註冊---通知---撤銷註冊”的形式。 觀察者Observer:所有潛在的觀察
Java的回撥函式和觀察者模式的區別
前一段時間研究了一下設計模式,突然想到觀察者模式和回撥函式之間的聯絡,網上也沒有什麼人說清楚,便自己又仔細想了想,便有了如下觀點,歡迎各位大神前來拍磚! 首先,先闡述一下網上說的,網上先說這是完全不同的兩種東西,介面回撥是觀察者模式的實現,後者是一種設計模式
Java描述設計模式(11):觀察者模式
本文原始碼:GitHub·點這裡 || GitEE·點這裡 一、觀察者模式 1、概念描述 觀察者模式是物件的行為模式,又叫釋出
重學 Java 設計模式:實戰觀察者模式「模擬類似小客車指標搖號過程,監聽訊息通知使用者中籤場景」
![](https://img-blog.csdnimg.cn/20200630231649444.png) 作者:小傅哥 部落格:[https://bugstack.cn](https://bugstack.cn) - `原創系列專題文章` >沉澱、分享、成長,讓自己和他人都能有所收穫!
JAVA設計模式之單例模式(轉)
單例對象 日誌 locking anti 常見 基本上 title 加載 懶漢式 本文繼續介紹23種設計模式系列之單例模式。 概念: java中單例模式是一種常見的設計模式,單例模式的寫法有好幾種,這裏主要介紹三種:懶漢式單例、餓漢式單例、登記式單例。 單例模式有以下特