SDK设计心得之接口设计

144 篇文章 13 订阅

由于SDK的特殊性,所以对于SDK的开发来说,一开始对于SDK的一些通用的整体的元素的设计至关重要。因为SDK(尤其很多平台SDK,使用的应用成百上千)一个及其细微的调整都会影响很多开发者的版本周期。因此前期的设计显得尤为重要。关于这部分内容,我会分两篇来介绍,这篇重点介绍具体接口的设计。另一篇SDK设计心得之架构和资源将重点介绍SDK的架构和一些资源的使用方式。

关于接口设计

设计原则

接口名称、参数名称要足够清晰

一个牛逼的接口名称可以替代无数的注释

一个接口只做一件事

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

举个让我很蛋疼的例子吧。估计说太直接了有人看到就知道我在批评他,委婉一点。我们有个功能有两个接口:一个是需要传参数,另一个不需要传参,两者的逻辑完全是独立的。本来是根据第一个原则设计了两个信、达也算雅的接口来实现。但是由于这部分内容接入比较复杂,加上又都是异步接口,所以接入成本确实比较高,然后有人反映能不能优化一下。然后优化的结果就是强制我们把两个接口合为一个,增加一个参数来标识最终调用的是带参数的接口还是不带参数的接口。我当时就懵逼了。但是又不能不改,实在是痛苦。

其实这里游戏反映接入成本高,我们应该是去分析什么原因引起的接口成本身高,能不能优化。不能直观的认为一个功能要两个接口,接口太多了接入成本就高,就要删接口。非把两个只是功能相关但是逻辑完全没有关系的接口合为一个带来最大的问题就是游戏的接入成本没有降低,但是自己的代码逻辑变得复杂了……

接口参数要尽可能少

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

好吧,在举个实际的例子,发现所有的经验都是血泪史,要哭了啊。我们有不少功能(其实就是分享)游戏调用的时候需要传递比较多的参数,而且这些参数有个共同点,都是String。有些参数调用了是直接展示出来的,有些参数是放在回调或者数据统计使用的,完全是不知道参数正确与否的。然后在某一次,有开发者调用的时候就把两个非关键值填反了,因为两个String,所以所有的调用都是通的,因为这两个参数调用以后都不是直接展示出来的,所以没有人发现掉错了。等到版本发布,数据量变大的时候,才发现统计结果和一个业务逻辑都有问题。最后问题的原因竟然真的就是两个String参数位置写错了!!!

对于这种问题,我们目前的做法是当有多个同一数据类型的参数时,直接把他们封装为一个Obj,调用的时候先给obj赋值,然后再调用,这样就大大减少了出错的几率。当然,这还是不能避免问题,比如下图这样的……

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

  • 所有接口参数必须要做合法性校验。不要让别的接口去保证调用你接口的参数一定是合法的。
  • 所有接口做的第一件事就应该是对参数做合法性校验。不要等到逻辑跑完大半了再告诉参数不合法,调用失败。Are u kidding me?
  • 对于需要转义、需要类型转换等的参数,一定要处理,而且尽量尽早的去处理,虽然客户端没有XSS或者SQL注入什么的,不代表你就可以不用考虑

实在不想再举例子了,这才写了一点,我就严重的感觉自己就是个loser,为什么什么问题我遇到过…………为了总结经验,还是正视自己吧。我们有一个接口,最开始只在一个地方用,而且调用和实现都是同一个人写的,所以他就偷懒没有做参数合法性校验。然后过了好多天,另一个同学开发了一个接口,也调用了之前的接口。然后问题来了:这个接口参数偶现Crash,最终定位是因为传递了个null进去,而被调函数没做参数合法性校验…………

通用的名称要统一

  • 即使再小的系统,也会有一些通用名词,对于一些通用名词或者模块的叫法、写法一定要统一。忽然发现在这一系列文档中,有很多东西自己叫的都不统一,又打脸了。

具体来说就是一些通用名词的写法一定要规范,其实大多数可以通过编码规范来避免,例如openid和open_id这种只要编码规范统一就不会同时出现。但是对于具体的名词就不好说了,比如openid,openID,openId,OpenID。这个我还能忍,但是对于QQ的写法我就不能忍了,QQ已经是一个名词,是一个标准的写法了,在QQ结构中看到qq也就算了,竟然还见过有人写Qq,这是什么鬼,什么鬼?!!再举一个微信的例子,写WXwechatweChatwxweixin的都有,这么多写法,晕不晕?让新来的同学怎么搞~~

又一次感概只有你想不到,没有程序猿哥哥做不到~~

关于同步和异步接口

  • 可以同步的接口,一定不要异步
  • 能不用全局回调就一定不要用全局的回调
  • 一定要用全局回调最好按照模块分开,一个模块一个回调。开发者只需实现他关心模块的回调即可。无关模块的回调设置与否对SDK的正常使用没有影响;另外每一个回调里最好又能区分回调属于哪次调用的字段。
  • 同一个回调里面的接口尽可能的少,可以合并的尽量合并。

个人感觉总结的已经比较到位了,就再讲讲我们怎么做的以及有什么优缺点。最开始我们所有模块公用同一个全局回调,因为当时模块也不多,而且都是必接模块,最关键是多个回调开发者接入的时候比较麻烦,所以选择了不区分模块把所有回调统一整合到一个全局回调。

随着业务发展,我们的SDK包含了越来越多的模块,有些模块是属于个性化的,小众需求的,再把他合到通用的全局回调并不合适,因为很多开发者并不使用这部分功能,却还要关心对应的回调。因此对于这些完全独立而且小众的需求开始使用自己的独立的全局回调。这样虽然解决了所有的问题,但是感觉太像小作坊的模式。因此建议还是最好一开始就按照模块各自设置独立的全局回调。

最新补充,最新的SDK中,我们已经在逐步弃用全局回调,直接在接口调用的时候让同步添加对应的接口回调。

关于多线程

关于多线程,其实本来和SDK关系不大,但是个人觉的有必要专门说明一下。就说一下下吧。关于多线程、handle是什么,用了有什么好处就不多说了,就简单总结几点吧。

关于UI线程

  • SDK除非必须,不要使用应用的主线程,就算使用也只能是简单操作,不能长时间占用。
  • SDK应该有一个专门的线程来处理SDK相关的操作。

这样做最主要的目的就是尽可能的减少SDK对应用本身的影响,尽可能减少SDK引起的ANR等问题。具体案例就不说了,太废话了。上面的结论就带来了下面的问题:既然UI进程的影响要尽可能小,那就带来一个进程间怎么通信的问题,Handle就是解决神器。

怎么使用handle

  • 所有耗时、异步操作都通过handle扔给SDK的线程去处理。处理结束以后再把结果通过handle发给主线程。
  • 任何时候主线程只做一件事,UI调整。所有的耗时操作:读取文件、读取DB、网络数据读取、网络请求发起等全部都要不要用UI线程去处理。

这里就不讲案例了,之前博客已经讲过一些因为主线程处理耗时操作引起的血淋淋的案例了。这里就说下目前个人比较常用的一个可能有耗时操作的函数的处理流程吧。

  1. 调用方调用接口
  2. 接口参数校验,校验合法,发给SDK的线程
  3. SDK的线程收到消息开始处理内部逻辑,处理结束发起回调
  4. 对返回结果进行二次处理,发给UI线程
  5. UI线程通过回调接口回调游戏

关于第三方平台

关于因第三方平台的限制引起的失败

每个SDK不可能都是完全独立的一部分,尤其是为业务服务的SDK,很可能都还会和周边SDK有一些交集。因此对于怎么处理和周边平台相关的一些逻辑也比较麻烦。这里简单汇总下从客户端的角度认为需要关注的点。

  • 对于非SDK内部逻辑的限制引起的接口不可用,不要直接判定为失败,而是让规则制定方去判定。而SDK本身可以加个Log提示,方便问题定位。原因有俩:
  1. 平台的规则可能会调整,到时候平台支持了,你不支持,就是你的问题
  2. 如果按照上面的方法操作,即使平台调整了,你也不用专门调整,尤其如果是客户端SDK,你不用专门出版本,游戏也不需要更新。因此我们就在违反规范以后打个错误日志,只要平台支持,接口还是可以用。

还是说具体的案例吧,不然显得干巴巴。我们的SDK会集成多个SDK,然后对于某些接口平台会有一些限制,比如分享的时候图片大小不能超过10M,缩略图不能超过32K等。最开始我们在做参数校验的时候发现图片大小超过规范以后打算直接返回失败,后来经过讨论,我们决定在超过大小以后打印一行错误日志,还是会去继续调用平台的接口,然后由平台接口调用失败以后回调给我们,我们再回调游戏。加上LOG以后游戏联调的时候,如果调用失败了,我们可以根据LOG快速定位到原因。上线一段时间以后,很多游戏反映32K太小了,果然和预期一致平台将大小改到了64K。那一瞬间,幸福如花儿一般绽放。

关于第三方平台的常量

  • 对于第三方平台的常量例如错误码等,最好是自己封装一层提供给开发者。不要直接将第三方平台暴漏给开发者

很多时候,开发者会通过一个SDK来同时集成和实现多个SDK的功能,这个时候开发者面对的只有一个SDK。如果你的SDK包含了或者集成了多个第三方的SDK,你要做的就是不要让开发者还需要了解其余SDK的东西。包括接入配置等。对于第三方平台的常量,不管是SDK自身还是最终的使用者,其实不会再调整但是SDK怎么处理还是很重要。不封装,开发者还需要关注周边SDK的内容,显得你不够专业;封装的话,万一第三方SDK有调整你也要调整(不要说不可能,我们就亲身经历了一个第三方SDK把常量名称和值都修改了的例子)。

为了防止上面的情况,建议封装第三方平台的常量的时候不要使用对方的常量值,而是直接使用对方的变量来赋值。例如:

public final static int eXXX = otherPlatform.eXXX;

关于第三方平台的配置

  • 对于第三方平台的各种配置,比如appid等,最好是仅仅用于第三方平台的逻辑中,不要为了省事把第三方平台的配置用于自己的业务逻辑

这个其实根据平台的自身需要了,建议既然是SDK,就是一个平台,还是有自己应用标识比较好(appid,appkey),虽然一开始用不到,但是有没有坏处。不要依赖第三方平台的一些应用配置信息做自己的逻辑。

再来一个赤裸裸的例子吧。我们最开始为了方便自己的一些前后台交互用了某个第三方平台的配置字段,后来接入另一个第三方平台,为了使用方便,我们经过协商也用相同的配置字段。嗯,感觉良好,然后有一天,有一个应用只接入第二个平台而不接入第一个平台,我们第一次懵逼了,但是当时偷懒了,没有根本解决这个问题,而是选择虽然不接入第一个平台,也去第一个平台配置这个字段~~~这就已经很傻了,还不赶紧改,第二波就来了,第一个平台忽然调整了那个配置字段,弃用了,换了新的字段来标示,同时值也变化了(他们做了兼容,可以同时支持新旧字段),但是第二个平台就瞬间跪了,只能二选一,用老的值,新版本有问题,用新的值,老版本有问题,瞬间煞笔了~~

关于配置

这里主要说一些关于模块开关,平台配置相关的内容。主要涉及到配置文件的处理和下发。这部分内容主要探讨一下吧,还没有很好的结果。

配置通过什么形式下发

不管是模块的开关还是接口的权限,都应该可以后台控制。当然前台最好也要有配置文件,可以减少一些无用的请求。而且在后台不能控制的时候,前台的开关还是很有必要的。

在同时有前后台的开关或者配置的时候,记得优先使用后台的配置,不然你搞个后台开关有毛用(不多说,亲身经历。)

配置放在什么位置

目前我们项目的配置文件放在assert目录下,目前遇到的问题是我们云端下发配置文件的时候比较麻烦。这里就出现另一个问题,云端下发是下发配置文件还是下发配置开关。如果下发配置开关,那就放在什么位置都可以,如果下发配置文件,配置文件下发在什么位置就很重要。

配置使用什么格式

  • 所有的配置文件用key-value的方式来保存
  • 所有的配置项的Key建议增加统一的前缀,例如MSDK_。当然我们目前的没有增加,所以就显得很混乱。别学我们。

SDK设计心得之接口设计 - 云+社区 - 腾讯云 (tencent.com)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
步骤一:引入JS文件 在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js 备注:支持使用 AMD/CMD 标准模块加载方法加载 步骤二:通过config接口注入权限验证配置 所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。 wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: '', // 必填,企业号的唯一标识,此处填企业号corpid timestamp: , // 必填,生成签名的时间戳 nonceStr: '', // 必填,生成签名的随机串 signature: '',// 必填,签名,见附录1 jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); 步骤三:通过ready接口处理成功验证 wx.ready(function(){ // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。 }); 步骤四:通过error接口处理失败验证 wx.error(function(res){ // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。 }); 接口调用说明 所有接口通过wx对象(也可使用jWeixin对象)来调用,参数是一个对象,除了每个接口本身需要传的参数之外,还有以下通用参数: success:接口调用成功时执行的回调函数。 fail:接口调用失败时执行的回调函数。 complete:接口调用完成时执行的回调函数,无论成功或失败都会执行。 cancel:用户点击取消时的回调函数,仅部分有用户取消操作的api才会用到。 trigger: 监听Menu中的按钮点击时触发的方法,该方法仅支持Menu中的相关接口
### 回答1: SDK详细设计文档是华为开发的一种技术文档,旨在提供给开发者使用华为提供的软件开发工具包(SDK)时的详细指导和帮助。该文档包含了对SDK的整体架构、各个模块的功能、接口定义、调用流程、数据结构等方面的详细描述。 首先,在SDK详细设计文档中,会对整体架构进行说明。这包括SDK的组成部分,如库文件、头文件、配置文件等,以及它们之间的关系和依赖关系。开发者可以通过了解整体架构,更好地理解SDK的使用方式和内部机制。 其次,文档会对各个模块的功能进行具体介绍。这些模块可能涉及到不同的功能领域,如网络通信、图像处理、数据存储等。通过详细描述每个模块的功能和特性,开发者可以更好地选择和使用所需的功能模块。 文档还会提供接口定义和调用流程的说明。对每个接口,会说明参数的含义、返回值的意义以及调用的具体步骤。这方面的详细描述有助于开发者正确使用接口,并根据自己的需求进行定制化开发。 此外,SDK详细设计文档会涉及到一些数据结构的定义和使用案例。这些数据结构可能用于传递参数、存储中间结果,或者表示特定的数据类型。开发者可以通过对数据结构的了解,更好地理解SDK中各个功能模块之间的数据交互方式,以及如何处理和解析数据。 总之,SDK详细设计文档是华为为开发者提供的一份关于SDK的详细说明和指南。通过阅读该文档,开发者可以对SDK的整体架构和各个模块的功能有更深入的理解,更好地利用SDK开发出适合自己需求的应用程序。 ### 回答2: 华为的SDK详细设计文档是华为公司为了帮助开发人员使用其软件开发工具包(SDK)而编的一份详细文件。这份文档旨在提供有关华为SDK的详细信息,以帮助开发人员了解并正确使用华为提供的各种功能和工具。 首先,SDK详细设计文档会提供关于华为SDK整体架构的概述,包括其组成部分和各个组件之间的相互关系。这有助于开发人员全面了解SDK的结构和功能,以便更好地应用它们。 其次,文档会提供各个组件的详细说明,包括每个组件的功能、接口和用法。开发人员可以通过这些详细说明,了解如何在他们的应用程序中使用特定的组件,以实现各种功能。 此外,文档还会提供示例代码和使用场景,以帮助开发人员更好地理解和应用SDK。这些示例代码可以作为开发人员在实际项目中的参考,以便更快地上手使用华为SDK。 最后,文档还会包含一些最佳实践和建议,以帮助开发人员优化他们的应用程序性能和使用华为SDK的效果。这些最佳实践是基于华为自身的经验和技术专长,可以让开发人员更好地利用华为SDK的各种功能和特性。 总之,华为的SDK详细设计文档是一份为开发人员提供详细信息的指南,旨在帮助他们正确地理解和使用华为SDK。它包含了整体架构、组件说明、示例代码和最佳实践等内容,以帮助开发人员更好地应用华为SDK,提高应用程序的质量和性能。 ### 回答3: 华为的SDK详细设计文档是为了帮助开发者在华为平台上使用软件开发工具包(SDK)进行应用程序开发的指南。该文档提供了全面的技术细节和指导,帮助开发者理解和使用SDK的各种功能和特性。 文档的结构通常包括以下几个方面: 1. 引言:介绍SDK的概述、目的和适用范围,以及文档的阅读指南。 2. 架构设计:详细说明SDK的整体架构和组成部分。这包括SDK的主要功能模块、接口和交互方式,以及各个模块之间的关系和依赖。 3. 功能描述:逐一介绍SDK的各个功能模块,并提供详细的功能说明和使用示例。这部分通常包括SDK的API接口、数据结构、操作流程等内容。 4. 性能优化:给出在使用SDK时进行性能优化的建议和指导。这包括了对关键性能指标的定义、优化方法和注意事项,以及性能测试和调试工具的介绍。 5. 集成指南:提供了SDK在各种开发环境和平台上的集成指南,包括开发工具的配置、开发环境的要求和软件库的导入。 6. 错误处理和异常情况:介绍在SDK使用中可能遇到的错误情况和异常处理方法。这包括了常见错误码的定义、错误处理流程和常见问题解答。 7. 附录:提供了一些额外的参考资料,如常用术语解释、示意图、代码示例等。 SDK详细设计文档的目的是为开发者提供全面且详尽的技术指导,帮助他们理解和使用华为的SDK。通过该文档,开发者可以更好地利用SDK的功能,加速应用程序开发过程,提高应用的性能和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值