Java的回调函数及模板方法
2013-04-20 20:32
169 查看
刚开始接触回调函数,确实感觉有点玄乎其玄,仔细多看看也就明白了。
Java的回调函数一般是这样用的:声明一个接口A,接口中定义一个回调方法doSomething(),然后在调用对象B的方法methodB()时,把接口A的一个实现a作为参数传进去,在methodB()方法体中通过a.doSomething()来实现回调。
一般情况下,我们需要调用哪个方法,就先实例化该方法所在类的一个对象,然后通过该对象取调用目标方法,一切似乎水到渠成,为什么还要用回调函数调来调去呢?在上面的回调过程中,在调用methodB()时,我们完全可以不传参数,在要调用doSomething()的时候再实例化一个接口A的实现。但是,这样做会导致一个问题,methodB()必须知道接口A的具体实现,这样灵活性就会大大降低,比如接口A换了一个实现就必须得改methodB()的代码。
举个例子:假设一个项目需要由项目经理和程序员两个人来共同完成,项目经理和程序员待定,10天后将项目情况反馈给客户。
首先,声明一个接口,定义一个回调方法:
在这个例子中,指定程序员编码用了回调。我们看ProjectManager类,项目经理在安排工作assignWork()的时候还没确定程序员,所以传入了一个Coding的接口,可以把这个接口比喻成所有会写代码的程序员名单。等到项目经理完成架构设计后,这时候心中已经有程序员人选了,然后在程序员名单中找到这个人选,即通过接口传入的对象来回调code()方法。
仔细想一想,我们是否可以让程序员跟项目经理那样用一个个不同的类来做呢?答案是肯定的,但是,如果有100个程序员,我们就得写100个类来描述每个程序员的能力,这样很不合理。而用回调函数,我们只要把100个程序员的名单传过去,程序员的能力如何暂时不管,等到项目经理要用人的时候,拿出名单选一个,再鉴定一下能力就行(这里用匿名类使代码更简洁,也可用内部类)。
另外,例子中还用到模板方法的思想,ProjectManager其实就是一个模板,它规定了项目的步骤是架构设计、编码实现、反馈客户这个流程,无论是哪个项目经理来负责这个项目都必须按照这个流程来进行,而流程中架构设计师怎样做的、程序员是怎样编码的,对于ProjectManager来说一概不关心,只要子类按照ProjectManager规定的方法来实现就行了。
Java的回调函数一般是这样用的:声明一个接口A,接口中定义一个回调方法doSomething(),然后在调用对象B的方法methodB()时,把接口A的一个实现a作为参数传进去,在methodB()方法体中通过a.doSomething()来实现回调。
一般情况下,我们需要调用哪个方法,就先实例化该方法所在类的一个对象,然后通过该对象取调用目标方法,一切似乎水到渠成,为什么还要用回调函数调来调去呢?在上面的回调过程中,在调用methodB()时,我们完全可以不传参数,在要调用doSomething()的时候再实例化一个接口A的实现。但是,这样做会导致一个问题,methodB()必须知道接口A的具体实现,这样灵活性就会大大降低,比如接口A换了一个实现就必须得改methodB()的代码。
举个例子:假设一个项目需要由项目经理和程序员两个人来共同完成,项目经理和程序员待定,10天后将项目情况反馈给客户。
首先,声明一个接口,定义一个回调方法:
package com.kinyoung; /** * 声明一个接口,提供回调的方法 * @author Kinyoung * */ public interface Coding { /** * 程序员能否在指定时间内完成编码工作 * @param dayRemain 剩余的编码天数 */ public void code(int dayRemain); }接着,定义项目经理类,项目经理的能力和水平不一样,这里用抽象类:
package com.kinyoung; /** * 将项目经理进行抽象 * @author Kinyoung */ public abstract class ProjectManager { /** * 项目经理进行工作安排,任务步骤是固定的 * @param action */ public void assignWork(Coding action) { int dayToal = 10; System.out.println("项目计划在10天内完成!"); System.out.println("第一步:系统架构和设计"); int dayDesignCost = design(); System.out.println("第二步:编写代码"); //假设留给程序员写代码的天数依赖于架构设计所用的天数 //此处是通过传入对象来调用code()方法的,实现回调 action.code(dayToal - dayDesignCost); System.out.println("第三步:反馈客户"); feedback(); } /** * 不同项目经理的能力是不一样的,其架构设计的思想及细节是不同的,留给子类去实现 * @return 架构设计所用的天数 */ protected abstract int design(); /** * 反馈相关信息给客户 */ private void feedback() { System.out.println("完成/未完成任务!"); } }然后,来个具体的项目经理,初级的、高级的、打酱油的都有,我们随便来一个吧:
package com.kinyoung; /** * 高级项目经理 * @author Kinyoung */ public class SeniorProjectManger extends ProjectManager { /** * 高级项目经理的设计能力果然比较强 */ @Override protected int design() { System.out.println("我是高级项目经理,只需要3天时间就能完成设计!"); return 3; } }按理接下来应该指定个程序员的,但程序员实在太多了,找谁好呢?暂时还没想好,先做个估算,看一下项目能否按时完成吧:
package com.kinyoung; /** * 测试一下看能不能按时完成项目任务 * @author Kinyoung */ public class Test { public static void main(String[] args) { ProjectManager pm = new SeniorProjectManger(); //找哪个程序员来完成编码呢? pm.assignWork(new Coding(){ //想到要找哪个程序员了 @Override public void code(int dayRemain) { System.out.println("只剩下" + dayRemain + "天的时间来完成"); System.out.println("我是菜鸟,需要8天才能写完代码!"); //System.out.println("我是大牛,我只需要5天就能写完代码!"); if (dayRemain < 8) { System.out.println("结果:不能按时完成!"); } else { System.out.println("结果:按时完成!"); } } }); } }运行结果:
项目计划在10天内完成! 第一步:系统架构和设计 我是高级项目经理,只需要3天时间就能完成设计! 第二步:编写代码 只剩下7天的时间来完成 我是菜鸟,需要8天才能写完代码! 结果:不能按时完成! 第三步:反馈客户 完成/未完成任务!
在这个例子中,指定程序员编码用了回调。我们看ProjectManager类,项目经理在安排工作assignWork()的时候还没确定程序员,所以传入了一个Coding的接口,可以把这个接口比喻成所有会写代码的程序员名单。等到项目经理完成架构设计后,这时候心中已经有程序员人选了,然后在程序员名单中找到这个人选,即通过接口传入的对象来回调code()方法。
仔细想一想,我们是否可以让程序员跟项目经理那样用一个个不同的类来做呢?答案是肯定的,但是,如果有100个程序员,我们就得写100个类来描述每个程序员的能力,这样很不合理。而用回调函数,我们只要把100个程序员的名单传过去,程序员的能力如何暂时不管,等到项目经理要用人的时候,拿出名单选一个,再鉴定一下能力就行(这里用匿名类使代码更简洁,也可用内部类)。
另外,例子中还用到模板方法的思想,ProjectManager其实就是一个模板,它规定了项目的步骤是架构设计、编码实现、反馈客户这个流程,无论是哪个项目经理来负责这个项目都必须按照这个流程来进行,而流程中架构设计师怎样做的、程序员是怎样编码的,对于ProjectManager来说一概不关心,只要子类按照ProjectManager规定的方法来实现就行了。
相关文章推荐
- Java 是如何利用接口避免函数回调的方法
- paip.函数方法回调机制跟java php python c++的实现
- java学习之旅50--面向对象_23_回调的实现_模板方法模式
- 【GOF23设计模式】_模板方法模式_钩子函数_方法回调_好莱坞原则JAVA249
- paip.函数方法回调机制跟java php python c++的实现
- java设计模式-模板方法(方法回调,钩子函数)
- 使用继承或接口实现模板方法的方式与函数回调的感悟
- java回调方法、钩子方法以及模板方法模式
- Java回调机制与模板方法设计模式
- java回调方法、钩子方法以及模板方法模式
- js 利用iframe和location.hash跨域解决的方法,java图片上传回调JS函数跨域
- JNI(Java Native Interface)多线程回调方法
- JNI层线程回调Java函数示例
- java回调方法
- Java Web开发——FreeMarker模板使用方法讲解
- JAVA设计模式(17):行为型-模板方法模式(Template Method)
- java设计模式(八)--模板方法模式
- Java中关于函数回调和反射机制的介绍
- java 策略模式 模板方法 (Template method) 示例
- thinkPHP模板中函数的使用方法示例