一.基本概念
if you call me, i will call back
什么是回調函數
回調函數(callback Function),顧名思義,用於回調的函數。 回調函數只是一個功能片段,由用戶按照回調函數調用約定來實現的一個函數。回調函數是一個工作流的一部分,由工作流來決定函數的調用(回調)時機。回調函數包含下面幾個特性:
1、屬於工作流的一個部分;
2、必須按照工作流指定的調用約定來申明(定義);
3、他的調用時機由工作流決定,回調函數的實現者不能直接調用回調函數來實現工作流的功能;
回調機制
回調機制是一種常見的設計模型,他把工作流內的某個功能,按照約定的接口暴露給外部使用者,為外部使用者提供數據,或要求外部使用者提供數據。
java回調機制:
軟件模塊之間總是存在着一定的接口,從調用方式上,可以把他們分為三類:同步調用、回調和異步調用。
同步調用:一種阻塞式調用,調用方要等待對方執行完畢才返回,它是一種單向調用;
回 調:一種雙向調用模式,也就是說,被調用方在接口被調用時也會調用對方的接口;
異步調用:一種類似消息或事件的機制,不過它的調用方向剛好相反,接口的服務在收到某種訊息或發生某種事件時,會主動通知客戶方(即調用客戶方的接口)。
回調和異步調用的關系非常緊密:使用回調來實現異步消息的注冊,通過異步調用來實現消息的通知。
二.舉例說明
1.簡單調用
(1) 接口實現需要回調的方法
public interface CallBack { //需要回調的方法 String event public void postExec(); }
(2) 最終實現類 FooBar。 擁有參數為CallBack接口類型的函數,setCallBack(ICallBack o)
public class FooBar { // 組合聚合原則 private CallBack callBack; //設置接口函數 public void setCallBack(CallBack callBack) { this.callBack = callBack; doSth(); } //執行接口函數 public void doSth() { System.out.println("FooBar 執行 "); callBack.postExec(); } }
(3) test
public class CallBackTest { public static void main(String[] args) { FooBar foo = new FooBar(); foo.setCallBack(new CallBack() { @Override public void postExec() { System.out.println(" 在Test類中實現但不能被Test的對象引用,而由FooBar對象調用"); } }); } }
2.使用已實現的類調用
(1) 接口實現需要回調的方法
public interface ServiceProvider { public void customHintCallBack(); }
(2) 最終實現類 ChinaTelecom
public class ChinaTelecom { private ServiceProvider sp; //callback接口作為屬性 private boolean isHappened=true; public void setSp(ServiceProvider sp) { this.sp = sp; } public void doWork() { System.out.println("Welcome, This is ChinaTelecom! "); if (isHappened) { // 事件發生時,通過調用接口的這個方法來通知 sp.customHintCallBack();//sp自定義的操作 } } }
(3) 接口實現需要回調的方法
//實現接口 class KongNet implements ServiceProvider { @Override public void customHintCallBack() { System.out.println("優惠活動開始啦!"); } }
(4) Test
public static void main(String[] args) { ChinaTelecom ct = new ChinaTelecom(); //使用匿名類,調用自定義方法 ct = new ChinaTelecom(); ct.setSp(new ServiceProvider() { @Override public void customHintCallBack() { System.out.println("優惠活動開始啦 test1! "); } }); ct.doWork(); //使用已實現的類實現回調 ct.setSp(new KongNet()); ct.doWork(); //使用已實現的類實現回調,自定義方法 ct = new ChinaTelecom(); ct.setSp(new KongNet() { @Override public void customHintCallBack() { super.customHintCallBack(); System.out.println("優惠活動開始啦! end back!!!"); } }); ct.doWork(); }
3.設計模式實現消息通知
(1) 定義一個接口InterestingEvent ,回調方法nterestingEvent(String event) 簡單接收一個String 參數
public interface InterestingEvent { // 這只是一個普通的方法,可以接收參數、也可以返回值 public void interestingEvent(String event); }
(2) 實現InterestingEvent接口,事件處理類
class CallMe implements InterestingEvent { private String name; public CallMe(String name){ this.name = name; } @Override public void interestingEvent(String event) { System.out.println(name + ":[" +event + "] happened"); } }
(3) 事件管理者,或事件通知者
public class EventNotifier { private List<CallMe> callMes = new ArrayList<CallMe>(); public void regist(CallMe callMe){ callMes.add(callMe); } public void doWork(){ for(CallMe callMe: callMes) { callMe.interestingEvent("sample event"); } } }
(4) 測試
public class CallMeTest { public static void main(String[] args) { EventNotifier ren = new EventNotifier(); CallMe a = new CallMe("CallMe A"); CallMe b = new CallMe("CallMe B"); // regiest ren.regist(a); ren.regist(b); // test ren.doWork(); } }
