這篇想寫有段時間了,因為前兩週有個工作多年的同行在問,callback是什麼....但一直沒寫的原因是不想畫圖,不想寫sample code...
Callback是什麼?看起來很容易啊,就"叫回去"咩...似乎"回去叫"比較符合文法,這是簡單基本的東西,連Design Pattern都不屑列進去,但是只寫Java的人可能比較不能想像,因為Java沒有function pointer,所以比較不容易舉例,反而是寫過C(++),JavaScript的人比較容易理解.
簡單說, Callback就是將function當做參數傳給被呼叫的程式, 只碰Java的應該就頭大了,將function(method)當參數?!
先談談程式運作的模式吧,用別人的Library寫系統有幾種方式,
一是事必躬親,站在旁邊看著別人做完一步,再決定下一步要做什麼
二是先告訴對方我是誰,能做什麼事,等他有空時要處理我的工作時候再叫我過去
三是留紙條給他,叫他照著辦,心情好再留個電話給他,叫他辦完時要回報一下
第一種情形像什麼,用過JDBC library的應該很清楚,
Connection conn = ds.getConnection(...); PreparedStatement preStat = conn.prepareStatement(...); preStat.setObject(....) .... preStat.execute(); conn.close();很熟悉吧?
第二種情形呢,比較像是用Observer Pattern來做事
interface Observable { public void notifyObservers(); public void register(Observer obs); public void unRegister(Observer obs); } interface Observer { public void available(Observable ob); }
Observable利用Observer.available()來告訴Observer說我現在有空了,一起來玩吧...當然也可以讓Observable呼叫Observer的其他method來做事,只是這代表這兩個人要夠熟,不過由於是別人寫的API,所以Observable要完全認識你所寫Observer的機會不太高,只好將這定成Interface,能做的事情都定在Interface上囉
第三種就直接明瞭
class ThatCallsBack:public class Caller{ public: ThatCalls(T *who,void (T::*func)(void)): callee(who),callback(func){} void click() {(callee->*callback)();} private: T *callee; void (T::*callback)(void); };我就給你一個Function跟我的大名,自己看著辦!酷!
二三這兩種模式在Multithread的系統經常被使用,但Java缺少了關鍵性的function pointer,所以怎麼看都少了點fu.雖然Java沒有function pointer,但利用第二種做法還是可以寫出很有callback fu的API,第一種模式寫的JDBC程式可以改成下面這樣
Interface CallbackStatement { String hereIsMyStatement(); Object[] hereAreMyParameters(); void letMeKnowIfThereIsAnyProblem(String msg); } Interface SQLExecutor() { void execute(CallbackStatement cs); }這樣勉強算是callback吧,其實Spring的JDBCTemplate就是大量用這種方式來工作的喲