zoukankan      html  css  js  c++  java
  • java回调方法、钩子方法以及模板方法模式

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

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

    回调对象的引用(地址)作参数传递给另一个方法,当这个引用被用来调用其所指向的方法时,我们就说这是回调方法。回调方法不是由该方法的实现方直接调用,
    而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

         

    下面我们来通过一个小需求来实现回调,需求为:王钢蛋去餐厅打饭,餐厅服务员根据其饭量为其打饭。我们先构思下,首先要有个接口,接口中定义个抽象方法为
    饭量(回调接口);其次创建王钢蛋(回调类),让王钢蛋实现这个接口,并想好其饭量(回调方法);最后创建餐厅,餐厅服务员(另一方)接待王钢蛋(回调对
    象)并根据其提供的饭量(回调方法)打饭(特定事件,该事件会调用回调方法)。上代码:

    复制代码
    /**
    * 顾客,去食堂吃饭有个前提,要告诉服务员其饭量,才会给你盛饭
    *
    @author coder

    *
    */
    interface Client{
    /**
    * 告诉服务员其饭量
    *
    @return
    */
    public String appetite();
    }

    class WangGangDan implements Client{

    @Override

    public String appetite() {

    return "一车米饭";

    }

    }

    /

    食堂

    /

    class Restaurant{

    /


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

    *
    @param client 排队的客户

    *
    @return

    */

    public String dozenRice(Client client){

    return "盛了"+client.appetite();

    }

    }

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

    public static void main(String[] args) {

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

    Restaurant waiter=new Restaurant();

    String dozenRice
    =waiter.dozenRice(laowang);

    System.out.println(dozenRice);
    //最后老王“盛了一车米饭”

    //但是通常我们打饭时不会告诉服务员我们叫什么,这样太麻烦了,那么可不可以只告诉服务员

    //饭量多少就给我们打饭呢?按常理来说我们去餐厅也只会要一次饭。

    //匿名内部类多用来实现回调,简便

    String dozenRice1=waiter.dozenRice(new Client(){

    @Override

    public String appetite() {

    return "一锅米饭";

    }});

    System.out.println(dozenRice1);

    }


    }

    复制代码

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

    复制代码
    /**
    * 模板方法模式:在一个方法中定义一个算法的骨架,而将一些步
    * 骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情
    * 况下,重新定义算法中的某些步骤。
    * 【钩子方法】:原理就是实现为空的方法,在某任务之前、之后、
    * 执行中、报异常后调用的方法(是不是有种熟悉的感觉)。
    * 通常钩子方法是通过抽象类或是本类中的空方法来实现的。
    *
    */
    abstract class Client{
    /**
    * 【模板方法】
    */
    public void templateMethod(){
    before();
    appetite();
    after();
    }
    /**
    * 【钩子方法】在盛饭前(一个空的实现)
    */
    protected void before(){};
    /**
    * 【抽象方法】告诉服务员其饭量
    *
    @return 饭量
    */
    public abstract void appetite();
    /**
    * 【具体方法】盛饭后
    */
    private void after(){
    //实际项目这里是共有的业务逻辑
    System.out.println("拿筷子,找桌子,开吃...");
    }
    }
    /**
    *食堂
    */
    class Restaurant{
    /**
    * 打饭方法,前提是客户要告知服务员你的饭量,他会根据你的饭量给你“盛”饭
    *
    @param client 排队的客户
    *
    @return
    */
    public void dozenRice(Client client){
    client.templateMethod();
    }
    }

    public class Test1 { //业务处理类,老王去打饭
    public static void main(String[] args) {
    Restaurant waiter
    =new Restaurant();
    waiter.dozenRice(
    new Client(){
    @Override
    protected void before() {
    System.out.println(
    "对服务员吹胡子瞪眼!!");
    }
    @Override
    public void appetite() {
    System.out.println(
    "盛了一锅米饭");
    }});

    }
    }
    复制代码

        

  • 相关阅读:
    HDU 2116 Has the sum exceeded
    HDU 1233 还是畅通工程
    HDU 1234 开门人和关门人
    HDU 1283 最简单的计算机
    HDU 2552 三足鼎立
    HDU 1202 The calculation of GPA
    HDU 1248 寒冰王座
    HDU 1863 畅通工程
    HDU 1879 继续畅通工程
    颜色对话框CColorDialog,字体对话框CFontDialog使用实例
  • 原文地址:https://www.cnblogs.com/jpfss/p/9229289.html
Copyright © 2011-2022 走看看