如何设计C/S架构的Android SDK | 1. 如何设计一套易用的API?

52 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 6 天,点击查看活动详情

API接口是客户端直接集成调用的部分,我们应该保证它易用、稳定。

基本流程

  1. 如果功能是基于第三方的SDK实现(例如:接入新的硬件),需要仔细阅读原厂的SDK文档,弄清楚原厂API的功能方法参数与返回值的含义是同步还是异步接口 以及调用逻辑

  2. 根据SDK的功能需求,对需要实现的API进行适当归类、参数精简,定义可能存在的状态,画出 SDK的有限状态机图

上图为MediaPlayer的有限状态机图。有限状态机有助于我们梳理出SDK的所有状态,以及状态之间如何通过调用API进行转换。为了保证SDK的健壮性,实现时必须确保当用户未按照我们的预期时序调用API时,SDK也能够给出正确的反馈(抛出异常或返回值提醒)。

通常API会包含两大类,一类是功能的初始化和销毁接口,另一类则是具体的功能调用接口。

初始化和销毁接口并不是必要的。如果在使用具体的功能接口之前,需要进行IPC绑定、资源申请、Context依赖等初始化操作,建议提供初始化接口进行统一的初始化操作。若初始化接口打开了系统资源,还需提供销毁接口,进行主动的回收操作,防止内存泄漏。

  1. 按照基本的设计原则去设计实现每一个接口。

设计原则

  • 接口简单易用

    API开箱即用,简单明了,不要设计错综复杂的配置预初始化,最多调用init()就可以直接使用。

  • 方法和参数的名称要足够清晰

    一个好的接口名称可以替代无数的注释。方法名是一个动词,采用大小写混合的方式,第一个单词的首字母小写,其后单词的首字母大写。参数名应简短且富于描述,即能够支持其用途,尽量避免单个字符的变量名。

  • 一个接口只做一件事

    一个接口只做一件事。如果有两个比较接近的功能,但是用一个接口实现有点麻烦,那就用两个接口,不要为了减少接口而生硬地把两个接口合为一个。

  • 接口参数要尽可能少

    接口调用的参数要尽可能少,SDK能自身获取的就不要让开发者继续传递,尽可能少的在一个接口中使用同一数据类型的参数,如果确实很多,建议封装一个参数类作为Object参数。

  • 接口参数要一定要校验、需要转义或者转换的一定要尽可能早的处理

    所有接口做的第一件事就应该是对参数做合法性校验。不要等到逻辑跑完大半了再告诉参数不合法,调用失败。在实现时可以通过接口返回值告诉用户,也可以直接抛出IllegalArgumentException等异常。

  • 返回值的含义要足够明确

    开发者通过返回值,可以明确知道接口的调用结果。如果是返回值基本数据类型,可以要在SDK中进行常量定义,方便用户引用,通过常量名称就知道返回值含义。

  • 耗时的接口,需要异步实现

    从易用性上来讲,可以同步实现接口,一定不要异步。但是,SDK中的接口调用不能导致业务调用线程的长时间阻塞。异步实现的回调,注意调用线程保持统一。

  • 不要使用全局回调

    一次回调对应一次调用结果。不要将多次调用的结果通过一个回调返回。

  • 尽量减少使用第三方库

    SDK需要保持精简,第三库的引入会增加应用的大小,同时有可能与应用引用库发生冲突。