關於回調:
java
回調是觀察者模式以及反應堆模式的基礎react
一句話,回調就是一種雙向調用模式,什麼意思呢,就是說,被調用方在被調用時也會調用對方,這就叫回調。「If you call me, i will call back」。
先看看這個能夠說比較經典的使用回調的方式:算法
背景1:class A 實現接口inA設計模式
背景2:class A 中包含一個對於class B的引用b 網絡
背景3:class B有一個參數爲InA的方法test(InA a) 併發
class A的對象a調用B的方法傳入本身(因爲形參是個inA a),test(a) ——這一步至關於you call me.框架
而後b就能夠在test方法中調用InA的方法(已經將形參:接口a的引用傳入了) ——這一步至關於I call you back.異步
能夠參考下面的代碼:ide
//最基本的回調模式實現: public interface inA { public void callBacka(); } public class A implements inA{ //含有個B的實例 B b=new B(); @Override public void callBacka() { // TODO Auto-generated method stub System.out.println("excute the method in class A"); } } public class B { public void test(inA a){ a.callBacka(); } public void excuteB(){ System.out.println("excute the method in class B"); } }
能夠看出來,A類能夠經過a.b得到b的實例來調用b中的方法,執行完以後,在B類的對應方法中,能夠經過傳入的A的參數,來實現對於A的方法的回調,這個是很關鍵的。函數
回調還能夠實現異步操做,好比說,你有一個複雜的問題解決不了,打電話給你的同窗,你的同窗說能夠解決這個問題,可是須要一些時間,那麼你不可能一直拿着電話在那裏等,你會把你的電話號碼告訴他,讓他解決以後打電話通知你。回調就是體如今你的同窗又反過來撥打你的號碼。
結合到前面所分析的,你打電話給你同窗就是【you call me】,你同窗解決完以後打電話給你就是回調【i call you back】。
兩個關鍵點:
一、A類中包含一個B的引用,做爲其屬性
二、B類的須要回去到A的方法中,包含一個方法,這個方法的形參是對於A類的引用。
三、回調方法須要用接口實現,這樣A能夠經過集成接口,實現不一樣類型的回調方式。
再總結一下:軟件模塊之間老是存在着必定的接口,從調用方式上,能夠把他們分爲三類:同步調用、回調和異步調用。同步調用是一種阻塞式調用,調用方要等待對方執行完畢才返回,它是一種單向調用;回調是一種雙向調用模式,也就是說,被調用方在接口被調用時也會調用對方的接口;異步調用是一種相似消息或事件的機制,不過它的調用方向恰好相反(注意這個是與以前的的例子相反的),接口的服務在收到某種訊息或發生某種事件時,會主動通知客戶方(即調用客戶方的接口)。回調和異步調用的關係很是緊密,一般咱們使用回調來實現異步消息的註冊,經過異步調用來實現消息的通知。(貌似僅僅是用途不一樣而已 實質上差很少)同步調用是三者當中最簡單的,而回調又經常是異步調用的基礎。
觀察者模式(Observer)
觀察者模至關因而回調模式的擴充。在觀察者模式中,觀察者至關於上面例子中的A,被觀察者至關於上面例子中的B。不一樣的是有多個觀察者,一個被觀察者,也能夠是多個。
觀察者模式的官方定義:
觀察者模式定義了對象間的一種一對多依賴關係,使得每當一個對象改變狀態,則全部依賴於它的對象都會獲得通知並被自動更新。
當一個被觀察者的狀態發生改變 全部依賴它的對象都發生變化。
該模式的幾個角色:
Subject(被觀察的對象接口 ),規定ConcreteSubject的統一接口。
每一個Subject能夠有多個Observer,(經過在具體實現類中添加觀察者引用的ArrayList或者其餘相似方式來實現,這是實現回調方式的關鍵),觀察者是先於被觀察者建立的,而且要將對於觀察者的引用加入到被觀察者的ArrayList中,這樣才能在被觀察者的信息改變了以後通知對應的觀察者。(由於觀察者是先於被觀察者而建立的 而最後要經過被觀察者來調用觀察者,進行信息的更新,即後建立的,反過來調用先建立的對象,因此是回調)
ConcreteSubject(具體被觀察對象)
維護對全部具體觀察者的引用的列表,狀態發生變化時會發送通知給全部註冊的觀察者。(經過列表中對於obversor的引用,來是實現回調,更新觀察者)
從功能上來說,ConcreteSubjec至少要包含 addobservor(添加一個觀察者) deletobservor(刪除一個觀察者) 以及updateobservor三個部分,經過updateobservoer來進行回調,對觀察者進行更新,或者是通知觀察者來執行相對應的事務。
Observer(觀察者接口)
規定ConcreteObserver的統一接口;
定義了一個update()方法,在被觀察對象狀態改變時會被調用。
ConcreteObserver(具體觀察者)
維護一個對ConcreteSubject的引用,(這個能夠經過對於ConcreteSubject進行引用,以此來調用ConcreteSubject中的方法,好比添加刪除之類的操做,這樣的話,不用在main函數中生成ConcreteSubject的具體的類了,每個observer都含有add delete的方法)
特定狀態與ConcreteSubject同步,實現Observer接口,經過update()方法接收ConcreteSubject的通知。(回調過來的具體執行部分)
具體分析見下面的代碼,將obversor寫成了witcher。
//定義觀察者接口 public interface iWatcher { public void update(String str); } //定義被觀察者接口 public interface iSubject { public void add(iWatcher w); public void delete(iWatcher w); //修改觀察者類中的信息 public void update(String str); } public class concreteWatcher implements iWatcher { private String str; private int id; public void setId(int id) { this.id=id; } public int getId(){ return id; } //構造函數 public concreteWatcher(String str,int id){ this.str=str; this.id=id; System.out.println("the str is created:"+str+this.getClass().hashCode()); } @Override public void update(String str) { // TODO Auto-generated method stub this.str=str; System.out.println(this.getId()+" the str is updated:"+str); } } public class concreteSubject implements iSubject{ //含有一個觀察者的隊列 list是觀察者隊列的引用 ArrayList<iWatcher>list=new ArrayList<iWatcher>(); @Override public void add(iWatcher w) { // TODO Auto-generated method stub list.add(w); } @Override public void delete(iWatcher w) { // TODO Auto-generated method stub list.remove(w); } //體現回調的是在這個地方 @Override public void update(String str) { // TODO Auto-generated method stub //因爲List是自身類的屬性 不用經過方法在去傳了 //這裏是一個回調 watcher中的方法去進行更新 for(iWatcher w :list){ w.update(str); } } } package com.designpatten.Observer; public class Test { //生成三個觀察者 public static void main(String []args){ concreteWatcher a1=new concreteWatcher("watcher1",1); concreteWatcher a2=new concreteWatcher("watcher2",2); concreteWatcher a3=new concreteWatcher("watcher3",3); //生成一個被觀者 即抽象主題 concreteSubject sub=new concreteSubject(); sub.add(a1); sub.add(a2); sub.add(a3); sub.update("update the information"); } } //執行結果 /* the str is created:watcher11580958233 the str is created:watcher21580958233 the str is created:watcher31580958233 1 the str is updated:update the information 2 the str is updated:update the information 3 the str is updated:update the information */
關於反應堆模式(reactor)
反應器模式(Reactor pattern)與觀察者模式(Observer pattern)在這個方面極爲類似:當一個主體發生改變時,全部依屬體都獲得通知。不過,觀察者模式與單個事件源關聯,而反應器模式則與多個事件源關聯 。
Reactor Pattern 是一種爲處理服務請求併發提交到一個或者多個服務處理程序的事件設計模式,當請求抵達後,服務處理程序使用多路分配策略,而後同步地派發這些請求至相關的請求處理程序。
Observer patten只是監聽一個固定的主題,在reactor patten中,至關於subject的實現實例中同時包含了不一樣的Aarrylist每一個對應一個事件,每個事件被觸發,傳到subject中,相對應的Arraylist中引用的類就會被更新(所謂的進行註冊過的事件)
在reactor模式中,資料中經常會提到一個Hook Method 便是鉤子方法,這個是模板模式的一部份內容,具體的能夠參考一下後面列出的連接。
這裏就是簡單總結一下:
從模板模式的角度來看,方法被分紅三類:具體方法,抽象方法,鉤子方法。
一、具體方法就是咱們平時所寫的最多見的最普通的方法。
二、抽象方法在java中就是abstract方法,就是所謂的繼承,這個也比較常見。在一個執行過程當中幾個函數的出現順序一致,可是每一個步驟於在子類中可能有不一樣的實現,就直接繼承,迪對不一樣的抽象類進行不一樣的實現便可,這個的核心思想是在父類中提供了一個算法的框架,子類只能聽從這個框架來,可是具體每一個步驟的實現上可能有差異。最典型的就是sort函數,每次排序時,能夠自定義排序規則,這個可能會設計到具體不一樣的領域,可是sort函數的整個實現的大的步驟,則是徹底固定的。
三、鉤子方法其實就是反過來了,利用鉤子方法,子類能夠必定程度上影響父類的執行流程,鉤子方法的返回結果一般爲bool型變量,經常將父類中(模板方法)的某一個步驟放在if語句中,若是鉤子方法返回true則執行,返回false則不執行。在子類中能夠根據實際狀況對鉤子方法進行覆蓋,並對其默認返回值進行修改,從而肯定合適的模板方法的執行流程,至關因而子類影響了父類(模板方法)的執行流程。
相關參考資料:
http://blog.csdn.net/pi9nc/article/details/23169357 ( 這個感受比較通俗 )
http://1025250620.iteye.com/blog/1378538
http://daimojingdeyu.iteye.com/blog/828696
http://blog.csdn.net/fengxinze/article/details/7319059(這個是翻譯版本)
(確定是logserver對象先要生成 才能註冊到initial dispatcher中 才能進行回調 說實話 對於例子中的get_handler 看得仍是有點暈暈乎乎 先記錄在這裏)
模板方法模式
http://blog.csdn.net/lenotang/article/details/2911246
http://blog.csdn.net/lovelion/article/details/8299927
其餘各類網絡資料