設計模式_CallBack

一.基本概念java

  if you call me, i will call back設計模式

  什麼是回調函數
  回調函數(callback Function),顧名思義,用於回調的函數。 回調函數只是一個功能片斷,由用戶按照回調函數調用約定來實現的一個函數。回調函數是一個工做流的一部分,由工做流來決定函數的調用(回調)時機。回調函數包含下面幾個特性:
  一、屬於工做流的一個部分;
  二、必須按照工做流指定的調用約定來申明(定義);
  三、他的調用時機由工做流決定,回調函數的實現者不能直接調用回調函數來實現工做流的功能; app

  回調機制
   回調機制是一種常見的設計模型,他把工做流內的某個功能,按照約定的接口暴露給外部使用者,爲外部使用者提供數據,或要求外部使用者提供數據。
 java回調機制:
   軟件模塊之間老是存在着必定的接口,從調用方式上,能夠把他們分爲三類:同步調用、回調和異步調用。
  同步調用:一種阻塞式調用,調用方要等待對方執行完畢才返回,它是一種單向調用;
  回 調:一種雙向調用模式,也就是說,被調用方在接口被調用時也會調用對方的接口;
  異步調用:一種相似消息或事件的機制,不過它的調用方向恰好相反,接口的服務在收到某種訊息或發生某種事件時,會主動通知客戶方(即調用客戶方的接口)。
   回調和異步調用的關係很是緊密:使用回調來實現異步消息的註冊,經過異步調用來實現消息的通知。異步

二.舉例說明ide

  1.簡單調用函數

 (1) 接口實現須要回調的方法post

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) testthis

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.使用已實現的類調用spa

 (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();        
    }
}
相關文章
相關標籤/搜索