Java回調機制研究

來源:互聯網
上載者:User

標籤:java   回調   

1. 什麼是回呼函數

回呼函數,顧名思義,用於回調的函數。回呼函數只是一個功能片段,由使用者按照回呼函數呼叫慣例來實現的一個函數。回呼函數是一個工作流程的一部分,由工作流程來決定函數的調用(回調)時機。回呼函數包含下面幾個特性:

  (1)屬於工作流程的一個部分;
  (2)必須按照工作流程指定的呼叫慣例來申明(定義);
    (3)他的調用時機由工作流程決定,回呼函數的實現者不能直接調用回呼函數來實現工作流程的功能;

2.  回調機制

回調機制是一種常見的設計模式,它把工作流程內的某個供,按照約定的介面暴露給外部使用者,為外部使用者提供資料,或要求外部使用者提供資料。

3.java的回調機制

軟體模組之間總是存在這一定的介面,從調用方式上,可以把他們分為三類:同步調用、回調、非同步呼叫。

同步調用:一種阻塞式調用,調用方要等待對方執行完畢才能返回,它是一種單向調用;

回調:一種雙向調用模式,也就是說,被呼叫者在介面被調用時也會調用對方的介面

非同步呼叫:一種類似訊息或事件的機制,不過它的調用方向剛好相反,介面的服務在收到某種訊息或發生某種事件時,會主動通知客戶方(即調用客戶方的介面)。

回調和非同步呼叫的關係非常緊密:使用回調來實現非同步訊息的註冊,通過非同步呼叫來實現訊息的通知。

   我們暫且不討論回調的一些名詞和運行機制,首先說為什麼會存在回調這樣一種調用?同步和非同步機制的出現不必多說,大家心知肚明,那回調機製為什麼會出現呢?在我們現實生活中,有如下這樣情境:有一位老闆很忙,他沒有時間盯著員工幹活,然後他告訴自己的僱員,幹完當前這些事情後,告訴他幹活的結果。這個例子其實是一個回調+非同步例子,再舉一個例子,A程式員寫了一段程式a,其中預留了回呼函數介面,並封裝好了該程式,程式員B讓a調用自己的程式b中的一個方法,於是,他通過a中的介面回調自己b中的方法,到這裡你可能似懂非懂了,後面會繼續說明回調的出現原因。接下來我們把上面例子變成代碼,看到網上很多人最後搞混了非同步和回調,因此例子中不加入非同步呼叫。(注意:回調可不是解決什麼調用時間過長問題,那是非同步!)

首先建立一個回調介面,讓老闆得告知幹完活如何找到他的方式:留下老闆辦公室地址:

package net.easyway.test;    /**  * 此介面為聯絡的方式,不論是電話號碼還是聯絡地址,作為  * 老闆都必須要實現此介面  * @author Administrator  *  */  public interface CallBackInterface {        public void execute();  }  

建立回調對象,就是老闆本人,因為員工幹完活後要給他打電話,因此老闆必須實現回調介面,不然員工去哪裡找老闆?

package net.easyway.test;    /**  * 老闆是作為上層應用身份出現的,下層應用(員工)是不知道  * 有哪些方法,因此他想被下層應用(員工)調用必須實現此介面  * @author Administrator  *  */  public class Boss implements CallBackInterface {            @Override      public void execute() {          System.out.println("收到了!!" + System.currentTimeMillis());                }  }  

        建立控制類,也就是員工對象,他必須持有老闆的地址(回調介面),即使老闆換了一茬又一茬,辦公室不變,總能找到對應的老闆。
      package net.easyway.test;    /**  * 員工類,必須要記住,這是一個底層類,底層是不瞭解上層服務的  * @author Administrator  *  */  public class Employee {        private CallBackInterface callBack = null;            //告訴老闆的連絡方式,也就是註冊      public void setCallBack(CallBackInterface callBack){          this.callBack = callBack;      }            //工人幹活      public void doSome(){          //1.開始幹活了          for(int i=0;i<10;i++){              System.out.println("第【" + i + "】事情幹完了!");          }                    //2.告訴老闆幹完了          callBack.execute();      }  }  

          測試類別代碼:

        package net.easyway.test;    public class Client {        public static void main(String[] args) {                              Employee emp = new Employee();                    //將回調對象(上層對象)傳入,註冊          emp.setCallBack(new Boss());                    //開啟控制器對象運行          emp.doSome();      }    }  

          上面這個例子,大家可以和程式員A和程式員B的那個例子結合對照下。

        看了上面的例子,有的人可能認為,這不是面向介面的編程嗎?怎麼會是回調,你再好好想想,咱們面向介面的編程的調用關係?在三層中,當業務層調用資料層時,是不需要把業務層自身傳遞到資料層的,並且這是一種上層調用下層的關係,比如我們在用架構的時候,一般直接調用架構提供的API就可以了,但回調不同,當架構不能滿足需求,我們想讓架構來調用自己的類方法,怎麼做呢?總不至於去修改架構吧。許多優秀的架構提幾乎都供了相關的介面,我們只需要實現相關介面,即可完成了註冊,然後在合適的時候讓架構來調用我們自己的類,還記不記得我們在使用Struts時,當我們編寫Action時,就需要繼承Action類,然後實現execute()方法,在execute()方法中寫咱們自己的商務邏輯代碼,完成對使用者請求的處理。由此可以猜測,架構和容器中會提供大量的回調介面,以滿足個人化的定製。

         

        總之,要明確的一點是,首先要搞清回呼函數出現的原因,也就是適用情境,才能搞清楚回調機制,不然事倍功半。

        最後,再舉一例,為了使我們寫的函數接近完美,就把一部分功能外包給別人,讓別人個人化定製,至於別人怎麼實現不管,我唯一要做的就是定義好相關介面,這一設計允許了底層代碼調用高層定義的子程式,增強程式靈活性,和反射有著異曲同工之妙,我覺得這才是回調的真正原因,以上是我個人一些理解,望討論!


         

        Java回調機制研究

        聯繫我們

        該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

        如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

        A Free Trial That Lets You Build Big!

        Start building with 50+ products and up to 12 months usage for Elastic Compute Service

        • Sales Support

          1 on 1 presale consultation

        • After-Sales Support

          24/7 Technical Support 6 Free Tickets per Quarter Faster Response

        • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.