为什么国产 SDK 产品总是这么烂

现状

在微博上,吐槽国产 SDK 产品烂基本属于政治正确的月经贴:代码规范烂,接口烂,文档糟糕,不支持新特性等等。一般这种情况往往会归结于大厂的傲慢,懒,不作为和小厂的技术烂,而事实却并不如此简单。

定义

那么怎样才是一款优秀的 SDK,在我看来,至少要符合如下几个标准:

  • 完备的功能
  • 良好的接口规范
  • 完备且及时更新的文档
  • 良好的技术支持
  • 所用即所得,没有小动作。

当然我这里主要是指移动端 SDK,毕竟这是我比较熟悉的领域,但相信其他平台也是类似。

原因

作为一个使用过大量国产 SDK 产品(/(ㄒoㄒ)/~~)和参与开发了多款 SDK 产品的人,我认为大方向的原因可以归结为两个层面:技术层面和产品层面。

技术层面

先讲技术层面,首先需要明确的一点是,SDK 的开发难度较 App 开发有过之而无不及。撇开像微信分享这种量级的 SDK 不谈,大多数国内 SDK 往往需要提供相当复杂功能作为其云平台或平台服务的前端入口,如 IM SDK ,支付 SDK,直播推拉流 SDK,音视频 SDK 等,这些服务 SDK 不仅需要各自端的开发经验,同时也需要相关方向的多年积累,相对于普通的 App 开发难度自然上升。以科大讯飞为例,众所周知他们是国内语音识别方面的佼佼者,绝大多数需要使用语音识别的场景都会使用他们的 SDK,但只要看过他们的 iOS SDK 接口设计就会感受到一股浓浓的 C++ 混合匈牙利命名法 的味道,更是让人回忆起十几年前我们被微软 COM API 设计理念 所支配的恐怖。这就是典型的有业务能力积累却缺少对应端开发经验的情况。 (题外话:一个妹子温柔善良持家有道和你心灵相通,但是长相一般甚至丑陋,你要不要?逃。

而另一个增加 SDK 开发难度的因素是接入方的不可预计性。在日常开发中,不同模块互相调用的地方非常容易成为 bug 滋生的重灾区。究其原因无非是对各自模块使用方法做了 想当然但不符实际 的设想,导致结果和预期有出入,而这仅是平常团队协作且源码可见的情况。当一个外部接入者面对不开源的 SDK 又会做怎样的假设呢?这非常依赖于 SDK 开发者对各种使用场景的理解,对一些非常规的做法的控制和保护。在云信某个版本之前,我们都假设在这么一个移动先行的环境下,对于 IM 用户而言,在线状态是无关紧要甚至无用的。无论是 iOS 还是安卓都有对应的推送机制保证将消息及时通知到对端,使得我们不用在意当前用户是否像 PC 时代是否端坐在电脑前,所以我们并不提供在线状态这一功能。然而仍有一些客户强烈要求这个功能,结果一位客户巧妙利用我们聊天室在线人数无上限的机制,将所有线上用户加入同一个聊天室,通过聊天室的进出通知变相获取用户在线状态。这种做法的确可以完成客户需求,但却会因为一个小需求对服务器和 SDK 造成巨大的困扰,所以在设计 SDK 时需要用户场景做一定的假想,保护和规避,而这也对 SDK 开发者提出了更高的要求。

在开发模式方面,国内互联网公司多推行 快糙猛 的模式:快速迭代发版,重热更新,轻单元测试/接口测试,将产品快速投递到用户端,并通过快速的迭代进行改进。然而这套适应 App开发的模式并不适合 SDK 产品开发。一方面 SDK 产品的受众是公司,开发者,他们更重视的是功能实用性和稳定性,也没有很大动力对已集成 SDK 做持续升级 — 这将消耗大量的时间回归已稳定功能。另一方面,这种模式容易造成 SDK 开发过程中没有进行很好的设计规划,各版本功能间接口兼容性问题凸显:要么版本与版本之间经常有接口差异,要么为了保证版本兼容性引入大量冗余接口。这极其考验工程师在 API 方面的设计能力,对很多资深工程师尚且是件难事,更何况是刚入行的工程师。毕竟在他们看来 API 仅仅是 Application Programming Interface 的缩写。但实际上,API 更应该是 Applciation Programmer Interface 的缩写,毕竟代码虽然是给计算机运行,但更重要的是给人阅读。 (曾经见过某个 SDK 一个方法有十几个参数,再加上 OC 语言本身就极为啰嗦,每次调用该方法就让人怀疑人生

对于 App 开发者而言,当产品上线后,后续的跟进工作基本都交到市场和运营团队,开发团队仅需要跟进小部分用户反馈和线上问题,绝大部分工作往往是后续版本的开发和迭代。这个观念很容易从 App 开发迁移到 SDK开发:使得文档工作变成一份无人监督和审核的业余工作。一旦这样,文档的准确性和可读性只能依靠对应工程师的经验和自觉,很容易找成文档缺乏,客户引导不够等问题。绝大多数国内 SDK 产品都仅有寥寥几段对产品做完整性介绍和引导的文档,更多的是 API 的罗列,使得开发者在接入阶段需要花费大量时间猜测使用方法,甚至通过反复试验的方式来确认 API 的作用和参数意义。

产品层面

如果说技术层面的问题可以通过招人,培训和指定规范等方法改进,像一些大厂已经渐渐向 AWS 学习,引入完整的流程,招聘文档工程师,加强运营,技术支持和开发的互动 —- 好吧,其实也并不是这么简单。但产品层面的问题(定位)则基本是无解的。

我们都知道在免费网游中,大量的免费玩家在厂商看来并不是真正的用户,而是养肥贡献给大 R 的小嫩羊而已,这并不是说厂商有多无耻,而仅仅是由于商业利益所决定的。反观 SDK 提供商也一样,大量免费服务提供商的 SDK 往往会私自收集大量用户数据,这是符合他本身的商业利益的。而像微信分享,微博风险这样的 SDK 本身没有太大收集用户信息的意愿,但也没有足够的意愿做好它,只是提供一份刚好能用的版本而已。基本可以断定,在对应的团队中根本没有专门团队或专门人员进行开发,基本属于 面向实习生开发。于是乎在 iOS 上现在很多免费 SDK 被爆出私自收集用户资料,或是不支持 bitocde,仍使用 MRC 等等落后主流技术选择数年的状况也就见怪不见了。

而反观收费提供商的 SDK,前期的确有各种问题:接口别扭,功能不稳定,文档不完善等等,但他们的改进意愿和态度则更强烈和更端正,像上架所必须的 bitcodeipv6https 等支持往往会在第一时间甚至提前推出。而针对前期人力不足,经验不足造成的版问题,部分厂商会采取壮士断臂式的策略:fork 设计不佳的 SDK,进行大面积的改良工作,直接出不兼容的新版本,不惜同时维护两个版本,以保证新旧客户较好的接入体验。

典型的屁股决定脑袋的表现。

总结

以上只是我的推测和吐槽而已。╮(╯▽╰)╭