代码行数减少 30-90%!多邻国从Java迁移到Kotlin的奇妙体验

简介:

云栖号资讯:【点击查看更多行业资讯
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!


1

英文学习 App Duolingo(多邻国)的 Android 版最初是使用 Java 开发的,并一直沿用了 5 年。两年后,它变成了 100% 的 Kotlin App!从代码可维护性和开发者满意度方面来看,这次迁移是一个巨大的成功。网上已经有很多 Kotlin 的学习资源,所以在这篇文章中,我们将重点介绍如何将一个有百万用户的 App 迁移到 Kotlin。

2

1. 为什么选择 Kotlin

2018 年初,我们开始考虑使用 Kotlin,当时 Android 对 Kotlin 的支持还不到一年时间,而且不知道 Kotlin 会像现在这样流行,也不知道它会取代 Java 成为 Android 的开发首选语言。

我们当时的主要预期:

  • 生产力。Kotlin 比 Java 要简洁得多,编写 Kotlin 代码速度更快,维护起来也更容易。它与 Java 的无缝互操作性以及添加语言新特性的方式让 Android 开发者可以轻松上手。
  • 稳定性。我们的代码库历史记录中有 100 多次提交都与“修复 NullPointerException 问题”有关,这些问题都来自 Java 代码。Kotlin 的 Null 安全特性避免了大部分 NullPointerException,让我们在代码评审期间可以更多地关注其他问题。
  • 开发者满意度。Stack Overflow 发布的 2018 年度开发者编程语言报告表明,Kotlin 是开发者最喜爱的编程语言之一,仅次于 Rust。我们的开发人员已经对公司内部另外两个主要平台的语言升级做出了积极的反应:在 iOS 应用程序中使用 Swift,以及使用 TypeScript 完全重写了 duolingo.com。
  • 当然,迁移也存在一些风险,主要是开发人员的时间成本问题。另一个担忧是 Kotlin 是否会像 CoffeeScript 一样,最后可能会被它的“影子”语言打败。
  • 最后,我们的 Android 开发人员一致认为,Kotlin 的好处很有价值,足以证明使用 Kotlin 开发新代码是合理的,尽管我们还没有准备好全面迁移所有的代码。

2. 让开发人员跟上进度

Duolingo 的所有 Android 开发人员每两周开一次例会,讨论最近和即将做出的平台变更和非正式的事后分析,并进行问答。前期的会议专门介绍 Kotlin,内容主要基于 Kotlin 官方语言指南、Kotlin Koans、Android 官方文档和 MindOrks 备忘单,等等。

然后,每个 Android 开发人员都分配到一些 Java 代码,负责将它们迁移到 Kotlin。我们让相对有 Kotlin 经验的开发人员担任“Kotlin checker”角色,让他们在代码评审期间分享最佳实践。这个角色的人数逐步增加,直到所有的 Android 开发人员都包含在内。

3. Kotlin 相关的开发工具

从一开始,我们就对 Kotlin 工具进行容器化,并在代码预提交和 GitHub 拉取请求状态检查中强制使用,以此来确保代码的一致性。

我们使用 detekt、IntelliJ Inspection、Android lint 和我们自己开发的基于正则表达式的 Splinter 来检查所有的 Kotlin 代码。

在代码自动格式化方面,我们在公司范围内使用了 ktlint,将其作为代码预提交 hook 的一部分。另一个工具是 IntelliJ Formatter,不过我们发现它在 Docker 中运行会慢一些。

在将 Java 代码减少到只有 10% 的时候,我们从 CI 管道中移除了 PMD、SpotBugs 和大部分检查工具。继续使用这些 Java 工具将会降低我们的开发速度,而且不会为我们提供太多的价值。

4. 转换 Java 代码

为了让代码转换的评审工作尽可能轻松,我们建议每个源文件的拉取请求至少包含三个单独的提交:

运行 IDE 的自动转换器。这个提交会造成代码行错乱,但不需要仔细检查,因为对于运行时来说通常是安全的,尽管可能会引入编译时错误。

修复编译错误。这些修复通常很容易进行,例如,在必要时添加 @JvmStatic 注解。

重构。开发人员需要重构代码,让代码更符合 Kotlin 的习惯,例如使用 sumBy 而不是 for 循环。

我们发现,将 Java 文件转换成 Kotlin 后,行数平均减少了 30% 左右,在某些情况下甚至减少了 90%!

虽然移植代码对于我们的 Android 平台工程师来说不是问题,但对于我们的产品团队来说可能会相对困难。我们鼓励产品团队的开发人员在空闲时间迁移经常修改的代码,还通过每天的排行榜比赛来游戏化这个过程。最终,产品团队的开发人员担起了一半的工作量。

5. 绊脚石

Kotlin 的工具生态系统比 Java 的要小得多。尽管如此,它已经足够满足我们的需求了。

我们偶尔还是会遇到 NullPointerException 和 IllegalArgumentException,这些异常来自第三方 Java 依赖库(比如 Android 框架本身),它们没有遵循最佳实践,没有使用可空注解,以至于 Kotlin 编译器无法知道某些方法的参数或返回值可以为空。随着谷歌给它们的公共 API 加入注解,这种情况得到了改善。

不过,Kotlin 仍然缺乏对一些 Java 特性的原生支持,包括不太常见的超类静态受保护方法调用和神秘的超类构造函数调用,但这类问题很容易解决。

6. 结果

在 2018 年初引入 Kotlin 之前,我们的 Android 代码库的代码行数每年增长 46%。两年过去了,我们加入了很多新特性,活跃的贡献者数量增加了一倍多,而我们的代码库现在几乎只和以前一样大!

根据 NPS 数据,这一次 Android 开发人员的满意度增加了 129 个点,大多数开发人员认为是采用 Kotlin(以及我们的工具)起到了主要作用。NPS 的数据具体为:

https://en.wikipedia.org/wiki/Net_Promoter

我们现在也同时使用 Python 和 Java 作为后端服务开发语言,这几乎不需要额外的工作量,因为我们可以重用现有服务中的 Java 代码和 Android 代码库中的 Kotlin 工具。

总的来说,在迁移到 Kotlin 之后,我们感到非常开心。我们也很高兴能够看到它在我们的公司内部和整个软件行业中的采用率不断增长!

【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/live

立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK

原文发布时间:2020-06-01
本文作者:Art Chaidarun
本文来自:“cocoachina”,了解相关信息可以关注“cocoachina”

相关文章
|
1天前
|
Java
如何解决使用若依前后端分离打包部署到服务器上后主包无法找到从包中的文件的问题?如何在 Java 代码中访问 jar 包中的资源文件?
如何解决使用若依前后端分离打包部署到服务器上后主包无法找到从包中的文件的问题?如何在 Java 代码中访问 jar 包中的资源文件?
7 0
|
3天前
|
Java Spring
Java 效率编码 必备插件 Lombok 让代码更优雅
该内容是一个关于Lombok插件的教程摘要:介绍了Lombok用于减少Java开发中的模板代码,提升效率;讲解了如何在IntelliJ IDEA中安装Lombok插件,以及在pom.xml中添加依赖;并提到了@Data注解能自动生成getter/setter、equals、hashCode和toString方法,@Slf4j注解自动处理日志,@Builder用于构建对象,以及@AllArgsConstructor和@NoArgsConstructor注解生成构造函数。还鼓励探索更多Lombok的注解用法。
|
3天前
|
Java 关系型数据库 测试技术
Java代码一键生成数据库文档(案例详解)
Screw是一个自动化数据库文档生成工具,能根据数据库表结构快速生成简洁、多格式(HTML、Word、Markdown)的文档,支持MySQL、MariaDB等多数据库。它使用Freemarker模板,允许用户自定义样式。依赖包括HikariCP数据库连接池和对应JDBC驱动。通过在Java代码或Maven插件中配置,可方便生成文档。示例代码展示了如何在测试用例中使用Screw。文档效果依赖于数据库中的表和字段注释。
|
3天前
|
NoSQL Java API
java一行代码实现RESTFul接口
Spring Data REST是构建在Spring Data之上的库,可自动将repository转换为REST服务,支持JPA、MongoDB、Neo4j、GemFire和Cassandra。无需手动创建Service和Controller层。要开始,需配置JPA数据源,创建实体类和Repository接口。快速实现REST接口,只需引入spring-boot-starter-data-rest Maven依赖,并在Repository接口上添加@RepositoryRestResource注解。
|
3天前
|
Java 编译器 Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【4月更文挑战第30天】在Android开发领域,Kotlin作为一种现代化的编程语言,因其简洁性和功能性受到了开发者的广泛欢迎。尽管与传统的Java相比,Kotlin提供了诸多便利,但关于其性能表现的讨论始终未息。本文将深入分析Kotlin和Java在Android平台上的性能差异,通过实际测试数据揭示两种语言在编译效率、运行速度以及内存占用方面的具体表现,并探讨如何利用Kotlin的优势来提升Android应用的整体性能。
|
6天前
|
Java 编译器 开发者
【JAVA】为什么代码会重排序
【JAVA】为什么代码会重排序
|
6天前
|
存储 自然语言处理 Java
【JAVA面试题】什么是代码单元?什么是码点?
【JAVA面试题】什么是代码单元?什么是码点?
|
7天前
|
Java 测试技术 Android开发
构建高效Android应用:探究Kotlin与Java的性能对比
【4月更文挑战第26天】 在移动开发领域,性能优化一直是开发者追求的重要目标。随着Kotlin的兴起,其在Android平台上的应用逐渐增多,但关于Kotlin与Java在性能方面的对比,社区中仍存在诸多讨论。本文通过实际的性能测试,分析比较了使用Kotlin和Java编写的Android应用在多个维度上的运行效率,旨在为开发者提供一个明确的性能参考,帮助他们在选择编程语言时做出更加明智的决策。
|
8天前
|
SQL Java 数据库
java代码中调用dao层查询接口,代码没有返回数据,打印出的sql查出了数据
java代码中调用dao层查询接口,代码没有返回数据,打印出的sql查出了数据
14 1
|
8天前
|
安全 Java 开发者
Java编程:深入探索其原理、特性与实战代码
Java编程:深入探索其原理、特性与实战代码
10 1