java 钩子_java回调方法、钩子方法以及模板方法模式

在面向对象的语言中,回调则是通过接口或抽象类来实现的,我们把实现这种接口的类称为回调类,回调类的对象称为回调对象,其处理事件的方法叫做回调方法。(摘自百度百科)

那么通过上面那句话将百度百科中的“回调函数”翻译成JAVA版:回调方法就是一个通过回调对象的引用(java中的引用存的是对象的地址)调用的方法。如果你把

回调对象的引用(地址)作参数传递给另一个方法,当这个引用被用来调用其所指向的方法时,我们就说这是回调方法。回调方法不是由该方法的实现方直接调用,

而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

下面我们来通过一个小需求来实现回调,需求为:王钢蛋去餐厅打饭,餐厅服务员根据其饭量为其打饭。我们先构思下,首先要有个接口,接口中定义个抽象方法为

饭量(回调接口);其次创建王钢蛋(回调类),让王钢蛋实现这个接口,并想好其饭量(回调方法);最后创建餐厅,餐厅服务员(另一方)接待王钢蛋(回调对

象)并根据其提供的饭量(回调方法)打饭(特定事件,该事件会调用回调方法)。上代码:

/*** 顾客,去食堂吃饭有个前提,要告诉服务员其饭量,才会给你盛饭

*@authorcoder

**/

interfaceClient{/*** 告诉服务员其饭量

*@return

*/

publicString appetite();

}class WangGangDan implementsClient{

@OverridepublicString appetite() {return "一车米饭";

}

}/***食堂*/

classRestaurant{/*** 打饭方法,前提是客户要告知服务员你的饭量,他会根据你的饭量给你“盛”饭

*@paramclient 排队的客户

*@return

*/

publicString dozenRice(Client client){return "盛了"+client.appetite();

}

}public class Test1 { //业务处理类,老王去打饭

public static voidmain(String[] args) {

WangGangDan laowang=new WangGangDan(); //王钢蛋以别名laowang去食堂要饭

Restaurant waiter=newRestaurant();

String dozenRice=waiter.dozenRice(laowang);

System.out.println(dozenRice);//最后老王“盛了一车米饭”//但是通常我们打饭时不会告诉服务员我们叫什么,这样太麻烦了,那么可不可以只告诉服务员//饭量多少就给我们打饭呢?按常理来说我们去餐厅也只会要一次饭。//匿名内部类多用来实现回调,简便

String dozenRice1=waiter.dozenRice(newClient(){

@OverridepublicString appetite() {return "一锅米饭";

}});

System.out.println(dozenRice1);

}

}

这里将利用模板方法模式来说明钩子方法是什么,许多设计模式都用到了回调,钩子之类的概念,这些基础点理解了,有些模式也就不那么晦涩难懂了,稍微改写下上面的代码就可以:

/*** 模板方法模式:在一个方法中定义一个算法的骨架,而将一些步

* 骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情

* 况下,重新定义算法中的某些步骤。

* 【钩子方法】:原理就是实现为空的方法,在某任务之前、之后、

* 执行中、报异常后调用的方法(是不是有种熟悉的感觉)。

* 通常钩子方法是通过抽象类或是本类中的空方法来实现的。

**/

abstract classClient{/*** 【模板方法】*/

public voidtemplateMethod(){

before();

appetite();

after();

}/*** 【钩子方法】在盛饭前(一个空的实现)*/

protected voidbefore(){};/*** 【抽象方法】告诉服务员其饭量

*@return饭量*/

public abstract voidappetite();/*** 【具体方法】盛饭后*/

private voidafter(){//实际项目这里是共有的业务逻辑

System.out.println("拿筷子,找桌子,开吃...");

}

}/***食堂*/

classRestaurant{/*** 打饭方法,前提是客户要告知服务员你的饭量,他会根据你的饭量给你“盛”饭

*@paramclient 排队的客户

*@return

*/

public voiddozenRice(Client client){

client.templateMethod();

}

}public class Test1 { //业务处理类,老王去打饭

public static voidmain(String[] args) {

Restaurant waiter=newRestaurant();

waiter.dozenRice(newClient(){

@Overrideprotected voidbefore() {

System.out.println("对服务员吹胡子瞪眼!!");

}

@Overridepublic voidappetite() {

System.out.println("盛了一锅米饭");

}});

}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值