模块间的调用:
在一个应用系统中,无论使用何种语言,必然存在模块之间的调用,调用方式存在以下几种:
1、同步调用
同步调用是最基本并且最简单的一种调用方式,类A的方法a() 调用类B 的b() ,一直等待b() 方法执行完,a() 才可以继续执行下去,这种调用方式适合方法b() 执行时间不长的情况 , 如果时间过长,a() 方法将一直阻塞等待,导致余下代码无法执行;
2、异步调用
异步调用是为了解决同步调用可能出现的阻塞问题,类A的方法 a() 通过新启线程的方式调用 类B 的b() 方法,代码接着往下走,无论b() 执行多长时间都不会阻塞a() 方法。但是这种方式有个问题,如果a() 方法需要b() 方法的运行结果,怎么办?
必须通过一定的方式对方法b() 的执行结果进行监听。
在java 中使用Future + Callable 的方式做到这一点。
3、回调
回调的思想:
- 类A的a() 方法调用类B 的b() 方法;
- 类B 的 b() 方法执行完毕主动调用类A 的 callback() 方法;
代码示例:
模拟一个老师回答学生问题的现象;
首先,需要定义一个回调接口:
package nc.demo;
public interface Callback {
/**
* 回调接口,原文出处http://www.cnblogs.com/xrq730/p/6424471.html
*/
public void tellAnswer(int answer);
public void tellAnswer(String answer);
}
此接口需要让A来实现,因为此接口包含B执行完要回调的方法。
其次,定义老师的接口,里面包含老师要执行的方法;
package nc.demo;
public interface TeacherInter extends Callback {
public void askQusetion();
}
第三、 定义具体的老师,老师提问问题,学生回答问题
package nc.demo;
public class YuTeacher implements TeacherInter {
private Student student;
public YuTeacher(Student student) {
super();
this.student = student;
}
@Override
public void tellAnswer(int answer) {
}
@Override
public void askQusetion() {
student.resolveQuestion(this);
}
@Override
public void tellAnswer(String answer) {
System.out.println(answer);
}
}
第四、定义学生接口
package nc.demo;
public interface Student {
public void resolveQuestion(Callback callback);
}
第五、学生实现类
package nc.demo;
public class Tom implements Student {
@Override
public void resolveQuestion(Callback callback) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
callback.tellAnswer(3);
}
}
总结起来,回调的核心就是回调方将本身即this传递给调用方,这样调用方就可以在调用完毕之后告诉回调方它想要知道的信息。回调是一种思想、是一种机制,至于具体如何实现,如何通过代码将回调实现得优雅、实现得可扩展性比较高,一看开发者的个人水平,二看开发者对业务的理解程度。