seo 网站地图优化,iis7.5 添加网站,塘厦企业网站推广公司,建网站公司联系方式模块间调用 在一个应用系统中#xff0c;无论使用何种语言开发#xff0c;必然存在模块之间的调用#xff0c;调用的方式分为几种#xff1a; #xff08;1#xff09;同步调用 同步调用是最基本并且最简单的一种调用方式#xff0c;类A的方法a()调用类B的方法b()#…模块间调用 在一个应用系统中无论使用何种语言开发必然存在模块之间的调用调用的方式分为几种 1同步调用 同步调用是最基本并且最简单的一种调用方式类A的方法a()调用类B的方法b()一直等待b()方法执行完毕a()方法继续往下走。这种调用方式适用于方法b()执行时间不长的情况因为b()方法执行时间一长或者直接阻塞的话a()方法的余下代码是无法执行下去的这样会造成整个流程的阻塞。 2异步调用 异步调用是为了解决同步调用可能出现阻塞导致整个流程卡住而产生的一种调用方式。类A的方法方法a()通过新起线程的方式调用类B的方法b()代码接着直接往下执行这样无论方法b()执行时间多久都不会阻塞住方法a()的执行。但是这种方式由于方法a()不等待方法b()的执行完成在方法a()需要方法b()执行结果的情况下视具体业务而定有些业务比如启异步线程发个微信通知、刷新一个缓存这种就没必要必须通过一定的方式对方法b()的执行结果进行监听。在Java中可以使用FutureCallable的方式做到这一点具体做法可以参见我的这篇文章Java多线程21多线程下其他组件之CyclicBarrier、Callable、Future和FutureTask。 3回调 最后是回调回调的思想是 类A的a()方法调用类B的b()方法类B的b()方法执行完毕主动调用类A的callback()方法这样一种调用方式组成了上图也就是一种双向的调用方式。 代码示例 接下来看一下回调的代码示例代码模拟的是这样一种场景老师问学生问题学生思考完毕回答老师。 首先定义一个回调接口只有一个方法tellAnswer(int answer)即学生思考完毕告诉老师答案 1 /**
2 * 回调接口原文出处http://www.cnblogs.com/xrq730/p/6424471.html
3 */
4 public interface Callback {
5
6 public void tellAnswer(int answer);
7
8 } 定义一个老师对象实现Callback接口 1 /**2 * 老师对象原文出处http://www.cnblogs.com/xrq730/p/6424471.html3 */4 public class Teacher implements Callback {5 6 private Student student;7 8 public Teacher(Student student) {9 this.student student;
10 }
11
12 public void askQuestion() {
13 student.resolveQuestion(this);
14 }
15
16 Override
17 public void tellAnswer(int answer) {
18 System.out.println(知道了你的答案是 answer);
19 }
20
21 } 老师对象有两个public方法 1回调接口tellAnswer(int answer)即学生回答完毕问题之后老师要做的事情 2问问题方法askQuestion()即向学生问问题 接着定义一个学生接口学生当然是解决问题但是接收一个Callback参数这样学生就知道解决完毕问题向谁报告 1 /**
2 * 学生接口原文出处http://www.cnblogs.com/xrq730/p/6424471.html
3 */
4 public interface Student {
5
6 public void resolveQuestion(Callback callback);
7
8 } 最后定义一个具体的学生叫Ricky 1 /**2 * 一个名叫Ricky的同学解决老师提出的问题原文出处http://www.cnblogs.com/xrq730/p/6424471.html3 */4 public class Ricky implements Student {5 6 Override7 public void resolveQuestion(Callback callback) {8 // 模拟解决问题9 try {
10 Thread.sleep(3000);
11 } catch (InterruptedException e) {
12
13 }
14
15 // 回调告诉老师作业写了多久
16 callback.tellAnswer(3);
17 }
18
19 } 在解决完毕问题之后第16行向老师报告答案。 写一个测试类比较简单 1 /**2 * 回调测试原文出处http://www.cnblogs.com/xrq730/p/6424471.html3 */4 public class CallbackTest {5 6 Test7 public void testCallback() {8 Student student new Ricky();9 Teacher teacher new Teacher(student);
10
11 teacher.askQuestion();
12
13 }
14
15 } 代码运行结果就一行 知道了你的答案是3 简单总结、分析一下这个例子就是 1老师调用学生接口的方法resolveQuestion向学生提问 2学生解决完毕问题之后调用老师的回调方法tellAnswer 这样一套流程构成了一种双向调用的关系。 代码分析 分析一下上面的代码上面的代码我这里做了两层的抽象 1将老师进行抽象 将老师进行抽象之后对于学生来说就不需要关心到底是哪位老师询问我问题只要我根据询问的问题得出答案然后告诉提问的老师就可以了即使老师换了一茬又一茬对我学生而言都是没有任何影响的2将学生进行抽象 将学生进行抽象之后对于老师这边来说就非常灵活因为老师未必对一个学生进行提问可能同时对Ricky、Jack、Lucy三个学生进行提问这样就可以将成员变量Student改为ListStudent这样在提问的时候遍历Student列表进行提问然后得到每个学生的回答即可这个例子是一个典型的体现接口作用的例子之所以这么说是因为我想到有些朋友可能不太明白接口的好处不太明白接口好处的朋友可以重点看一下这个例子多多理解。 总结起来回调的核心就是回调方将本身即this传递给调用方这样调用方就可以在调用完毕之后告诉回调方它想要知道的信息。回调是一种思想、是一种机制至于具体如何实现如何通过代码将回调实现得优雅、实现得可扩展性比较高一看开发者的个人水平二看开发者对业务的理解程度。 同步回调与异步回调 上面的例子可能有人会提出这样的疑问 这个例子需要用什么回调啊使用同步调用的方式学生对象回答完毕问题之后直接把回答的答案返回给老师对象不就好了 这个问题的提出没有任何问题可以从两个角度去理解这个问题。 首先老师不仅仅想要得到学生的答案怎么办可能这个老师是个更喜欢听学生解题思路的老师在得到学生的答案之前老师更想先知道学生姓名和学生的解题思路当然有些人可以说那我可以定义一个对象里面加上学生的姓名和解题思路不就好了。这个说法在我看来有两个问题 1如果老师想要的数据越来越多那么返回的对象得越来越大而使用回调则可以进行数据分离将一批数据放在回调方法中进行处理至于哪些数据依具体业务而定如果需要增加返回参数直接在回调方法中增加即可 2无法解决老师希望得到学生姓名、学生解题思路先于学生回答的答案的问题 因此我认为简单的返回某个结果确实没有必要使用回调而可以直接使用同步调用但是如果有多种数据需要处理且数据有主次之分使用回调会是一种更加合适的选择优先处理的数据放在回调方法中先处理掉。 另外一个理解的角度则更加重要就是标题说的同步回调和异步回调了。例子是一个同步回调的例子意思是老师向Ricky问问题Ricky给出答案老师问下一个同学得到答案之后继续问下一个同学这是一种正常的场景但是如果我把场景改一下 老师并不想One-By-One这样提问而是同时向Ricky、Mike、Lucy、Bruce、Kate五位同学提问让同学们自己思考哪位同学思考好了就直接告诉老师答案即可。 这种场景相当于是说同学思考完毕完毕问题要有一个办法告诉老师有两个解决方案 1使用FutureCallable的方式等待异步线程执行结果这相当于就是同步调用的一种变种因为其本质还是方法返回一个结果即学生的回答 2使用异步回调同学回答完毕问题调用回调接口方法告诉老师答案即可。由于老师对象被抽象成了Callback接口因此这种做法的扩展性非常好就像之前说的即使老师换了换了一茬又一茬对于同学来说只关心的是调用Callback接口回传必要的信息即可 转载于:https://www.cnblogs.com/xrq730/p/6424471.html