回调函数

2 篇文章 0 订阅
1 篇文章 0 订阅

何为回调函数

所谓回调,从字面意思理解就是,当任务/事情完成之后,回过头来完成/通知接下来要执行的动作。
一个简单的例子就是(小明遇到问题不能解决,向小王求助,问题给到小王,小王可能现在有事或者需要思考一段时间才能得出答案,而小明也不会一直等着小王解决,所以对小王说,解决后通知我一声,小明就去做其他事情了,前面所提到的解决后通知我,就是回调)。

一个简单的实现

public class Ming {
    public void getAnswer(String answer){
        System.out.println("Ming 解决问题,得到答案为 :" + answer);
    }

    public void resolve(String question){
        System.out.println("Ming 思考中...");
        System.out.println("Ming 问题太难,求助吧");
        Wang wang = new Wang(this,question);
        new Thread(){
            @Override
            public void run() {
                wang.resolve();
            }
        }.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Ming 看来要等很久,那我也去做其他事情了");
    }

    public static void main(String []args){
        Ming ming = new Ming();
        ming.resolve("1 + 1 = ");
    }
}

class Wang{

    private Object object;

    private String question;

    public Wang(Object questioner,String question){
        this.object = questioner;
        this.question = question;
    }

    public void resolve() {
        try {
            System.out.println("Wang 我现在有事待会儿帮你解决,解决后通知你");
            Thread.sleep(3000);
            String answer = question + " 的答案为 2";
            ((Ming)object).getAnswer(answer);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}

这是上面案例所示的最简单的代码实现,通过把回调所要通知的对象直接传入给被调用者。
这种方法实现既不优雅也存在很大的局限性。对于被调用方(可看作是提供服务方),被调用放回调时只能调用调用方的指定方法,当存在多个调用方时,调用方必须要有相同的方法名,作为被调用方的回调方法(即上述代码中的 getAnswer() 方法)。下面给出一个比较通用、优雅的写法:

public class BetterMing {
    public void getAnswer(String answer){
        System.out.println("BetterMing 解决问题,得到答案为 :" + answer);
    }

    public void resolve(String question){
        System.out.println("BetterMing 思考中...");
        System.out.println("BetterMing 问题太难,求助吧");
        BetterWang wang = new BetterWang(question);
        wang.setCallBack(new BetterWang.CallBack() {
            @Override
            public void resolveDone(String answer) {
                getAnswer(answer);
            }
        });
        new Thread(){
            @Override
            public void run() {
                wang.resolve();
            }
        }.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("BetterMing 看来要等很久,那我也去做其他事情了");
    }

    public static void main(String []args){
        BetterMing ming = new BetterMing();
        ming.resolve("1 + 1 = ");
    }
}

class BetterWang{

    private CallBack callBack;

    private String question;

    public BetterWang(String question){
        this.question = question;
    }

    public void setCallBack(CallBack callBack){
        this.callBack = callBack;
    }

    interface CallBack{
        void resolveDone(String answer);
    }

    public void resolve() {
        try {
            System.out.println("BetterWang 我现在有事待会儿帮你解决,解决后通知你");
            Thread.sleep(3000);
            String answer = question + " 的答案为 2";
            if(callBack != null){
                callBack.resolveDone(answer);
            }
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}

上述升级版代码,是在小王(服务提供方)创建一个接口,该接口由小明(需要服务方)实现,不管需要服务方怎样调用,服务提供方开放这个接口,实现由你决定。
举个栗子:当你住酒店时,酒店提供起床提醒服务,这个提醒有打电话、来房间唤醒等。其中你就是需要服务方,酒店时服务提供方,提醒服务是服务方开放的接口,具体实现由你决定。
由于java中直接将方法作为引用传递,所以通过内部接口的方式进行实现。
如有错误欢迎指正。

参考链接:传送门1 传送门2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值