共计 3239 个字符,预计需要花费 9 分钟才能阅读完成。
这篇文章主要介绍“API 的实现方法是什么”的相关知识,丸趣 TV 小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“API 的实现方法是什么”文章能帮助大家解决问题。
1 对外接口的设计准则
SDK 对外提供接口设计的基本原则是易用,易懂,易扩展,易监控。展开来可归纳为以下几个特性:
API 按照业务功能分类,但所有业务具有统一的调用风格。
API 不包含方法实现,接口的实现对调用者隐藏。
API 调用可跟踪。
在功能形式上,SDK 需要提供以下类型的 API:
功能接口:主动调用使用其提供的功能
同步接口:在调用线程完成函数调用,并立即返回结果。
普通异步接口:在后台线程完成函数调用,可以添加回调函数。
可中断异步接口:在后台线程完成函数调用,可以添加回调函数,可以中断调用。
回调接口:监听数据和状态改变。
2 业务的分类
SDK 包含多种业务,一部分是基础业务,另一部分是可选业务。比如用户认证服务、群服务等是基础业务;超大群服务、第三方推送服务等是可选业务。另外,不同的业务之间难免有相似的功能,如群服务和超大群服务中,都有添加群成员,拉取群消息等功能。因此,需要将不同的业务进行隔离,一方面方便业务功能的扩展与调整,另一方面方便函数的命名与用户的理解。
同一个业务下有多个 API,按照调用的主动性,分为回调接口和功能接口,分别放在与业务一一对应的接口类 Observer 和 Service 中。例如:用户认证服务下的所有回调接口和功能接口都位于 AuthServiceObserver 和 AuthService 中。其中由用户主动调用来实现功能的功能接口在 AuthService 中,如登录、登出等;而用于注册回调的回调接口都在 AuthServiceObserver 中,如监听在线状态、监听数据同步等。
每个 Service 中的功能接口根据执行的性质又分为三种,同步接口、普通异步接口和可中断异步接口。其中同步接口在调用线程立即执行;异步接口在后台线程执行,在调用线程返回可设置回调的 InvocationFuture 类型,最终结果在主线程回调;可中断异步接口和普通异步接口相似,但是返回的是继承自 InvocationFuture 的 AbortableFuture 类型,支持中断操作,用户可以通过主动调用来中断功能接口的执行。接口调用的线程切换流程如图 2.1 所示,业务功能和接口的分类如图 2.2 所示。
图 2.1 接口调用的线程切换流程
图 2.2 业务功能和接口的分类
3 API 的实现 3.1 API 的实现方式
为了实现这些目标,并考虑到实现简单,我们选用 Java 的动态代理类模型。外部调用者调用 API 时,得到一个动态代理 (Proxy) 对象,通过 Proxy 对象,将功能接口的调用全部转接到一个实现了 InvocationHandler 接口的类 ProxyHandler 上。再根据调用方法,执行注册 / 注销回调或者将调用请求分派到真正的实现类上,最后根据接口的返回类型进行返回或回调,如图 3.1 所示。
图 3.1 功能调用流程
和用户服务的接口类 AuthService 和 AuthServiceObserver 一样,SDK 也为其他的所有业务定义了接口类。所有接口类和实现类呈一一对应关系,可以方便地找到 API 对应的实现。
3.2 获取 Proxy 对象的方法
SDK 对外提供了静态方法 NimClient.getService(Class T clazz)来获取业务接口类对应的动态代理类。参数填入对应的接口类即可。例如:获取用户认证服务的接口类的方式为 NimClient.getService(AuthService.class),获取用户认证服务观察者的接口类的方式为 NimClient.getService(AuthServiceObserver.class)。
NimClient.getService 方法同步返回一个 Proxy 对象。该对象的构造方式为懒加载,业务被调用的时候才构造对应实例。如图 3.2 所示。
图 3.2 获取业务 Proxy 对象流程
生成 Proxy 对象基于 Proxy.newProxyInstance 方法,所有生成的 Proxy 对象都由专门的容器类来管理。以用户认证服务为例,第一次调用 NimClient.getService(AuthService.class)获取用户认证服务的 Proxy 对象时,容器理类创建一个对应的 Proxy 对象并缓存。之后再次获取用户认证服务 Proxy 对象时,容器类将缓存直接返回。
3.3 事务跟踪类
invoke 函数中有一个重要的事务跟踪类(Transaction),它记录了方法的同步异步属性、方法体和返回值要求等。Transaction 对象和他的实现方法是一一对应的。每次执行 invoke 方法,都会创建一个 Transaction 实例,并传输到真正的执行点去执行
执行完毕后,invoke 方法根据同步异步特性以及返回值,来确定功能函数的返回结果。如果是同步函数,则直接返回结果;如果是异步函数,则根据业务需求返回 InvocationFuture 或者 AbortableFuture。
3.4 API 的执行方式
NimClient.getService 返回的是动态代理类 ProxyHandler,它实现了 InvocationHandler 接口的 Object invoke(Object who, Method method, Object[] args)方法,用于代理所有功能接口。
API 执行方式,即 ProxyHandler 对 invoke 方法的实现方式,其大体步骤是加载事务、初始化判断、执行事务和返回,如图 3.3 所示。
图 3.3 代理执行的简要流程
执行事务这一环节还可以细分为回调接口的执行和功能接口的执行,如果是执行回调接口,则判断是否需要回调当前状态,如果是,则立即回调。
Transaction 的执行函数是 TransactionExecutor. execute 方法,送出 Transaction 后,invoke 方法会根据同步异步属性,决定是在当前线程执行,还是在后台线程执行。用于异步执行 Transaction 的后台线程是唯一的,如果有多个 Transaction 需要被异步执行,则会阻塞。
接口类的每个方法都被存进一个 Map 中,SDK 以方法签名实现了同名函数重载。执行 Transaction 时,通过方法所在的接口类找到对应的实现类,再调用对应的 invoke 方法即可。对于异步方法,invoke 方法的返回值不会被返回到上层,因此异步 API 函数的实现不用关心返回值。代理的详细执行流程如图 3.4 所示
图 3.4 代理的详细流程
3.5 异步方法的回调
对于异步方法,在 TransactionExecutor. execute 执行前,先基于 Transaction 生成对应的 AbortableFuture 的实现类 TransactionFuture,然后将其缓存,用于稍后的回调。异步方法执行完毕后,将子类返回到调用层。
在调用可中断异步接口后,同步返回的是 AbortableFuture 实例。调用方可以直接调用 abort 方法中止执行。例如:调用了用于下载消息附件的 downloadAttachment 函数后,由于文件太大,网络状况不好等情况需要取消下载时,可以主动调用 abort 方法来终止。调用方式如图 3.5 所示。可中断异步接口对应的 abort 方法由 SDK 内部实现,调用者不需要关心其实现方式。
图 3.5 abort 函数调用示例
TransactionFuture 回调的基本类型为 RequestCallback,SDK 在此基本类型中定义了 onSuccess、onFailed 和 onException 函数,分别用于在成功、失败和异常情况下根据执行结果的不同,回调到不同的函数。到此整个流程结束。
关于“API 的实现方法是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注丸趣 TV 行业资讯频道,丸趣 TV 小编每天都会为大家更新不同的知识点。