我报名参与金石计划1期应战——瓜分10万奖池,这是我的第4篇文章,点击查看活动概况

前语

我在Lyft的八年间,许多产品经理以及工程师经常想往咱们 app 里增加第三方库。有时候集成一个特定的库(比如 PayPal)是有必要的,有时候是防止除开发一些十分杂乱的功用,有时候仅仅只是防止c重复造轮子。

尽管这些都是合理的考量,但运用第三方库的危险和相关本钱往往被忽视或误解。在某些状况下,危险是值得的,可是在决定冒险之前,首先要能够明确的定义危险。为了使危险评价更加的透明和共同,咱们拟定了一个流程来衡量咱们将其集成到app有多大的危险。

危险

大多数大型组织,包括咱们,都有某种办法的代码检查,作为开发实践的一部分。对这些团队来说,增加一个第三方库就相当于增加了一堆由不属于团队成员开发,未经检查的代码。这破坏了团队一向坚持的代码检查原则,交付了质量不知道的代码。这给app的运行办法以及长时刻开发带来了危险,关于大型团队而言,更是对全体事务带来了危险。

运行时危险

库代码一般来说,关于体系资源,和app具有相同等级的拜访权限,但它们不必定运用团队为管理这些资源而拟定的最佳实践。这意味着它们能够在没有约束的状况下拜访磁盘,网络,内存,CPU等等,因而,它们能够(过度)将文件写入磁盘,运用未优化的代码占用内存或CPU,导致死锁或主线程延迟,下载(和上传!)许多数据等等。更糟糕的是他们会导致溃散,乃至溃散循环

其间许多状况直到 app 现已上架才被发现,在这种状况下,修正它需求创立一个新版别,并经过审阅,这一般需求许多时刻和本钱。这种危险能够经过一个变量操控是否调用来进行必定程度的操控,可是这种办法也并非万无一失(看下文)。

开发危险

引用一个搭档的话:“每一行代码都是一种担负”,对不是你自己写的代码而言,这句话更甚。库在适配新技术或API时或许很慢,这阻止了代码开发,或许太快,导致开发的版别过高。

库在采用新技术或API时或许很慢,阻止了代码库,或许太快,导致布置方针太高。每逢 AppleGoogle 每年发布一个新 OS 版别时,他们一般要求开发人员依据SDK的改变更新代码,库开发人员也有必要这样做。这需求协调共同的努力、优先事项的共同性以及及时完结作业的才能。

随着移动平台的不断改变,以及团队(成员)也不是原封不动,这将会成为一个继续不断的危险。当被集成的库不存在了,而库又需求更新时,会花许多时刻来决定谁来做。事实证明一旦一个库存在,就很少也很难被移除,因而咱们将其视为长时刻保护本钱。

商业危险

如同我上面所说,现代的操作体系并没有对 app 代码和库代码进行区分,因而除了体系资源之外,它们还能够拜访用户信息。作为 app 的开发者,咱们担任恰当的运用这部分信息,也需求为任何第三方库担任。

假如用户给了 Lyft app 地理位置授权,任何第三方库也将自动得获得授权。他们能够将那些(地理位置)数据上传到自己服务器,竞对服务器,或许谁知道还有什么地方。当一个库需求咱们没有的权限时,那问题就更大了。

同样,一个体系的安全取决于其最单薄的环节,但假如其间包括未经审阅的代码,那么你就不知道它到底有多安全。你精心设计的安全编码实践或许会被一个行为不当的库所破坏。苹果和谷歌实施的任何方针都是如此,例如“你不得对用户追寻”。

减少危险

当对一个库(是否)进行运用评价时,咱们首先要问几个问题,以了解对库的需求。

咱们内部能做么?

有时候咱们只需求简略的张贴仿制真实需求的部分。在更杂乱的场景中,库与自定义后端通讯,咱们对该API进行了逆向,并自己构建了一个迷你SDK(同样,只构建了咱们需求的部分)。在90%的状况下,这是首选,但在与十分特定的供应商或需求集成时并不总是可行。

有多少用户从该库中获益?

在一种状况下,咱们正在考虑增加一个危险很大的库(依据下面的标准),旨在为一小部分用户供给服务,一起将咱们的所有用户都暴露在该库中。 关于咱们以为会从中获益的一小部分客户,咱们冒了为咱们所有用户带来问题的危险。

这个库有什么传递依靠?

咱们还需求评价库的所有依靠项的以下标准。

退出标准是什么?

假如集成成功,是否有办法将其转移到内部? 假如不成功,是否有办法删去?

点评标准

假如此刻团队仍然期望集成库,咱们要求他们依据一组标准对库进行“评分”。下面的列表并不全面,但应该能很好地阐明咱们期望看到的。

阻断标准

这些标准将阻止咱们从技术上或许公司方针上集成此库,在进行下一步之前,咱们有必要处理:

过高的 deployment target/target SDKs。 咱们支持曩昔4年主流的操作体系(版别),所以第三方库至少也需求支持一样多。

答应证不正确/缺失。 咱们将答应文件与运用捆绑在一起,以确保咱们能够合法运用代码并将其归属于答应持有人。

没有抵触的传递依靠关系。 一个库不能有一个咱们现已包括但版别不同的传递依靠项。

不显现它自己的 UI 。 咱们十分小心肠使咱们的产品看起来尽或许统一,定制用户界面对此晦气。

它不运用私有 API 。 咱们不愿意冒 app 因运用私有 API 而被拒绝的危险。

首要关注点

闭源。 拜访源代码意味着咱们能够挑选咱们想要包括的库的哪些部分,以及怎么将该源代码与运用程序的其余部分捆绑在一起。 关于咱们来说,一个封闭源代码的二进制发行版更难集成。

编译时有警告。 咱们启用了“警告视为错误”,具有编译警告的库是库全体质量(下降)的杰出指示。

糟糕的文档。 咱们期望有高质量的内联文档,外部”怎么运用“文档,以及有意义的更新日志。

二进制体积。 这个库有多大?一些库供给了许多功用,而咱们只需求其间的一小部分。尤其是在没有拜访源码权限的状况下,这一般是一个全有或全无的状况。

外部的网络流量。 与咱们无法操控的上游服务器/端点通讯的库或许会在服务器封闭、错误数据被发回等时封闭整个运用程序。这也与我上面提到的隐私问题相同。

技术支持。 当事情不能正常作业时,咱们需求能够报告/上报问题,并在合理的时刻内处理问题。开源项目一般由志愿者保护,也很难有一个时刻线,但至少咱们能够自己进行修正。这在闭源项目是不或许的。

无法禁用。 尽管大多数库特别要求咱们初始化它,但有些库在实例化时更“自动”,并且在咱们不调用它的状况下能够自己执行作业。这意味着当库导致问题时,咱们无法经过功用变量或其他机制将其封闭。

咱们为所有这些(和其他一些)标准分配了点数,并要求工程师为他们想要集成的库汇总这些点数。尽管默许状况下,低分数并不难被拒绝,但咱们一般会要求更多的理由来继续前进。

最终

尽管这个过程看起来十分严厉,在许多状况下,潜在危险是假设的,但咱们有我在这篇博文中描绘的每个场景的实际例子。将评价记录下来并揭露,也有助于将相对危险传达给不熟悉移动平台作业办法的人,并证明咱们没有随意评价危险。

此外,我不想宣称每一个第三方库本质上都是坏的。事实上,咱们在Lyft运用了许多:RxSwiftRxJavaBugsnagSDKGoogle MapsTensorflow,以及一些较小的用于十分特定的用例。但所有这些要么都经过了充沛检查,要么咱们现已决定危险值得收益,一起对这些危险和收益的真实含义有了明晰的认识。

最终,作为一个专业开发人员提示:一直在库的API之上创立自己的笼统,不要直接调用它们的API。这使得将来替换(或删去)底层库更加简单,再次减轻了与长时刻开发相关的一些危险。