博客 design principle:模拟 android Button 控件点击事件 主要说了一下模拟 android 的 Listener 模式,其实这就是一种委派与回调机制的体现。


委派,也可以叫做委托,从字面上来理解的话,应该是委托其他类做事情而自己不做或者只做一部分工作;而回调,就是调用自己的方法。


在 java 中,这两种机制很类似,你姑且可以认为它们就是一码事。


推荐一篇博文给大家: Java中委托事件模型


java 中,实现委派和回调都是通过接口来实现的。下面举个小例子吧!


该例子是这样的(只是一个例子):


ProfessionalWorker 、SparetimeWorker 负责发射 Rocket,Rocket 类通过接口 IRocketDelegate 委派(或者说是回调) ProfessionalWorker 、SparetimeWorker自己发射。


总之,Rocket不做具体的事情。看实例代码:


IRocketDelegate.java源码

public interface IRocketDelegate {  

    public abstract long startAtTime();  

    public abstract long endAtTime();  

    public abstract void sendDidFail();
}  

共有三个方法,分别是用于计算 Rocket 发射时间、计算 Rocket 发射完毕的时间以及发送是否失败的。


Rocket.java源码

public class Rocket {  

    IRocketDelegate delegate = null;  

    public Rocket(IRocketDelegate delegate) {
        this.delegate = delegate;
    }  

    private long getRocketStartTime() {
        long startTime = delegate.startAtTime();
        return startTime;
    }  

    private long getRocketEndTime() {
        long endTime = delegate.endAtTime();
        return endTime;
    }  

    public boolean isOk() {
        // 超时0.1秒为失败
        if (getRocketEndTime() - getRocketStartTime() >= 100) {
            delegate.sendDidFail();
            return false;
        }
        return true;
    }  

}  

在这个类中,声明一个 IRocketDelegate 接口对象,使用该对象调用接口的方法。我们知道,接口不可以直接实例化,换句话说,实例化接口必须实现接口的所有方法。


那么,我们就把这些实现工作交给具体的发射者来完成。实现回调。


ProfessionalWorker.java源码

public class ProfessionalWorker implements IRocketDelegate {  

    @Override
    public long startAtTime() {
        System.out.println("startAtTime is call-back inProfessionalWorker!");
        return System.currentTimeMillis();
    }  

    @Override
    public long endAtTime() {
        System.out.println("endAtTime is call-back in ProfessionalWorker!");
        return System.currentTimeMillis();
    }  

    @Override
    public void sendDidFail() {
        System.out.println("ProfessionalWorker send Rocket fail !");
    }  

    public void send() {
        if (new Rocket(this).isOk()) {
            System.out.println("ProfessionalWorker send Rocket ok !");
        }
    }
}  


SparetimeWorker.java源码

public class SparetimeWorker {
    public void send() {
        boolean isOk = new Rocket(new IRocketDelegate() {  

            @Override
            public long startAtTime() {
                System.out.println("startAtTime is call-back in SparetimeWorker !");
                return System.currentTimeMillis();
            }  

            @Override
            public long endAtTime() {
                System.out.println("endAtTime is call-back in SparetimeWorker!");
                return System.currentTimeMillis() + 100L;
            }  

            @Override
            public void sendDidFail() {
                System.out.println("SparetimeWorker send Rocket fail !");
            }
        }).isOk();  

        if(isOk) {
            System.out.println("SparetimeWorker send Rocket ok !");
        }
    }
}  

这个类采用内部类的方式完成。


Test.java

public class Test {  

    public static void main(String[] args) {
        new ProfessionalWorker().send();  

        System.out.println("*********************************************");  

        new SparetimeWorker().send();
    }
}  

显示结果

endAtTime is call-back in ProfessionalWorker!
startAtTime is call-back inProfessionalWorker!
ProfessionalWorker send Rocket ok !
*********************************************
endAtTime is call-back in SparetimeWorker!
startAtTime is call-back in SparetimeWorker !
SparetimeWorker send Rocket fail !  

这就体现 Java 中的一句话 Don't call me,I'll call you. 其含义就是回调(或者委派/委托)。


android 中很多这样的用法,关于接口的好处还有很多,后续慢慢研究,记住一句话:面向对象面向接口编程。

design principle:java 回调与委派/委托机制的更多相关文章

  1. java类加载器及其委托机制

    1.什么是类加载器,类加载器父子结构.BootStrap-->ExtClassLoader-->AppClassLoader,级别依次降低 2.类加载器之间的父子关系和管辖范围 3.类加载 ...

  2. 破坏双亲委托机制的一些情况---Tomcat和JDBC,破坏后的安全问题

    采用双亲委托机制的原因 类加载器就是将字节码搬进jvm方法区的组件.我们知道,JVM识别加载进来的类是通过类加载器+类全名完成的,也就是说同一个类由不同类加载器加载进去的话就会被视为不同的类.jdk提 ...

  3. 关于Java类加载双亲委派机制的思考(附一道面试题)

    预定义类加载器和双亲委派机制 JVM预定义的三种类型类加载器: 启动(Bootstrap)类加载器:是用本地代码实现的类装入器,它负责将 <Java_Runtime_Home>/lib下面 ...

  4. Java 类加载体系之 ClassLoader 双亲委托机制

    Java 类加载体系之 ClassLoader 双亲委托机制 java 是一种类型安全的语言,它有四类称为安全沙箱机制的安全机制来保证语言的安全性,这四类安全沙箱分别是: 类加载体系 .class文件 ...

  5. ClassLoader类加载器 & Java类加载机制 & 破坏双亲委托机制

    ClassLoader类加载器 Java 中的类加载器大致可以分成两类: 一类是系统提供的: 引导类加载器(Bootstrap classloader):它用来加载 Java 的核心库(如rt.jar ...

  6. Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论

    Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论 创建用户自定义的类加载器 要创建用户自定义的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的f ...

  7. Java虚拟机JVM学习05 类加载器的父委托机制

    Java虚拟机JVM学习05 类加载器的父委托机制 类加载器 类加载器用来把类加载到Java虚拟机中. 类加载器的类型 有两种类型的类加载器: 1.JVM自带的加载器: 根类加载器(Bootstrap ...

  8. java类加载器学习2——自定义类加载器和父类委托机制带来的问题

    一.自定义类加载器的一般步骤 Java的类加载器自从JDK1.2开始便引入了一条机制叫做父类委托机制.一个类需要被加载的时候,JVM先会调用他的父类加载器进行加载,父类调用父类的父类,一直到顶级类加载 ...

  9. java回调机制及其实现(转)

    1. 什么是回调函数 回调函数,顾名思义,用于回调的函数.回调函数只是一个功能片段,由用户按照回调函数调用约定来实现的一个函数.回调函数是一个工作流的一部分,由工作流来决定函数的调用(回调)时机.回调 ...

随机推荐

  1. Quartz + Tablesaw 报表统计

    场景 在12 月份做的报表功能中,直接从 ES 查询一个月的数据.当数据量特别大时,查询速度会非常缓慢甚至查询失败.解决方案是使用定时任务,在每天凌晨指定时间自动查询前一天的数据,然后写入 CSV 文 ...

  2. 解决com.fasterxml.jackson.databind.JsonMappingException: No suitable

    原因:直接翻译,json格式,不匹配. 这原因坑爹啊,因为json格式不正确算一种原因. 还有一种就是接收的bean没有getter,setter方法. 最坑的一种就是数据无法被反序列化,list,m ...

  3. 去掉textarea和input在ios下默认出现的圆角

    -webkit-appearance:none;/*清除ios默认圆角*/ border-radius:0;

  4. vue mint-ui 实现省市区街道4级联动(仿淘宝京东收货地址4级联动)

    demo及源码地址 https://github.com/artiely/citypicker 先去下载一个“省份.城市.区县.乡镇” 四级联动数据,然后 引入 import { Picker } f ...

  5. HashMap 和 HashTable 区别

    来源:http://www.importnew.com/7010.html HashMap和Hashtable的区别 HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚 ...

  6. Android Studio精彩案例(六)《使用一个Demo涵盖补间动画所有知识》

    转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 元旦假期里,闲的无事,看到美团加载数据的动画,就突想写个Demo把动画知识集成一下.后来想了想,还是直接用一个Demo来把所有动画知识 ...

  7. ListView常见的优化方式简述

    ListView的优化 对于ListView来说,应该算是布局中几种最常用的组件之一了,使用也十分方便,下面个大家介绍一下两种常见的优化方式. 1.条目复用优化 其实listview的工作原理就是,l ...

  8. ubuntu初始化python3+postgresql+uwsgi+nginx+django

    一. postgresql 数据库 安装 apt-get update apt-get install postgresql 进入psql客户端 sudo -u postgres psql 创建数据库 ...

  9. Git之(六)标签管理

    发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本.将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来.所以,标签也是版本库的一个快照 ...

  10. Objective-C方法与函数的区别

    Objective-C方法与函数的区别 方法是唯对象所有 函数是不依赖于对象存在的 方法 函数 - (void)test; void test(); 方法是以减号 - 开头 - 类型要用()括起来 - ...