导读:在本文中,我们将深入探讨 Infobip 软件工程师在过去十多年中使用 Kotlin 的经验,了解 Kotlin 在 Infobip 的黄金时代,以及未来可能面临的挑战。从维护代码到技术选择的复杂性,从 Groovy 的辉煌到 Kotlin 的崛起,以及对 Kotlin 的优势和劣势的审视,本文将揭示 Infobip 在使用 Kotlin 过程中所取得的经验和教训。最后,我们将探讨 Kotlin 可能在未来的发展趋势,以及 2025 年可能成为关键时刻的原因。让我们一同探索,了解技术选型的深思熟虑和对未来的前瞻性思考。
在我作为 Infobip 软件工程师的十多年里,我大部分时间都花在维护代码上,而且很多时候是其他人的代码。
我有幸(或不幸,这取决于你怎么看),见证了许多不同技术在新项目中兴起和崩溃,很多时候这些技术再也不会在新项目中使用。
其中一次发生在 2014 年。负责创建和维护 Infobip 某产品的团队解散了,而我的团队被指派接手并维护它。这个产品集成了所有最新的技术——node.js、Cassandra、MongoDB、Redis、MSSQL、Groovy、Grails、ELK,等等。不重要的是谁、怎么样以及为什么选择了所有这些技术。唯一重要的是复杂度预算是疯狂的。
复杂性毁了这个项目
原团队花了一个多月的时间,只是为了在本地搭建好一切,以便能够启动项目并尝试各种可能性。很快,我被调到了另一个团队,任务是构建一个概念验证,一个 MVP 产品,它与我们应该维护的那个产品具有相同的功能,但使用的技术更少。
我们构建它的方式与我们在 Infobip 构建大多数东西的方式相似。只用了老套但实用的 Java 和 MSSQL,其他的就没了。那是在 2015 年,而这项服务直到 2023 年仍在运行。原始项目的复杂性毁了它。更糟糕的是,它也毁了原本应该维护它的团队。
故事的寓意是——你需要对你的复杂性预算特别小心。这不仅涉及你维护的服务或库的数量,还涉及你需要维护的各种技术的数量以及技术的未来前景。
当 Groovy 还是很炙手可热的时候
在 2013 年,JVM 上最炙手可热的语言之一不是 Java,而是 Groovy。它拥有 lambda、动态结构、命名参数构造函数,还有一个受欢迎的 Grails 框架等等。但是,就在 2014 年,仿佛没有人能预测到一样,Java 8 发布了一个新的热门功能——lambda。
Lambda 消除了当时 Java 一个最显著的负面评价——在代码中传递行为需要使用大量的匿名内部类。或者,俗称为——Java 没有 lambda。不久之后,大约在 2015/2016 年左右,Groovy 经历了显著的衰落。如今,它的使用显著下降,没有人在创建新服务时考虑使用它。
但是,JVM 生态系统的创新并没有随着 Groovy 的衰退而减弱,相反地,下一个受瞩目的新东西是 Scala!
有人还记得 Scala 吗?
我记得!我甚至完成了一门由 Scala 的作者 Martin Odersky 主持的 Coursera 课程,名为“Functional Programming Principles in Scala”。老实说,我对 Scala 的魅力比对 Groovy 的特性更为着迷。在 Java 中,我最缺少的就是模式匹配。通过简单的类似于 lambda 的表达式,而不是滥用访问者模式,来遍历复杂的数据结构。
在 Infobip 有一些用 Scala 编写的服务,但它从未起飞。在 2017 年左右,该语言的一个关键维护者离开,开始走下坡路。
Kotlin 的到来
下一个可能“淘汰 Java”的竞争者是 Kotlin。它慢慢崭露头角,但对我来说,真正开始起飞是在 2017 年左右,首先是我们的 People 产品创建时——后端是用 Kotlin 编写的,然后是我们的默认 Maven 父项目增加了对 Kotlin 的支持。第一个对我来说很重要,因为它是第一个大规模采用 Kotlin 的 Infobip 部署,而第二个标志着开始大规模采用。
Kotlin 的优势
与 Java 代码的互操作性
虽然它并非完美,但 Kotlin 在与 Java 代码的互操作性方面比它的前辈表现更好。这很可能是因为它出现在它们之后,能够从 Groovy 和 Scala 等语言的经验和陷阱中吸取教训。
它还不需要任何专门的构建工具(比如 Scala 的 sbt),并且具有与 IntelliJ 的插件和集成。它由最流行的 Java IDE 创建者 JetBrains 创造,这是一个很大的优势,但我将在后面的缺点列表中分享一个警告。
协程
在 Infobip 软件生态系统中,这实际上是一个重要的功能。它提供了一种在语法上廉价解决异步任务扩展问题的方式,特别是与 RxJava、Reactor、CompletableFutures 等相比。
直到 Java 21 发布之前,Java 没有这个功能的竞争对手,但随着 21 和虚拟线程的发布,它现在有了。明年将是决定其竞争力的关键时刻。
如果虚拟线程表现良好,减少了切换到 Kotlin 协程的价值,这将标志着 Kotlin 的衰落开始。特别是如果 JetBrains 没有提出一个带来很大价值的新热门功能的话。
数据结构和模式匹配
在引入 records(16)和模式匹配(21)之前,Lombok 是 Java 中唯一的替代方案。
我对 Lombok 的不喜欢程度超过了普通 Java 开发者,特别是因为它违反了 Java 中注解处理的第一规则——注解处理器不应修改 Java 编译器生成的 .classes 文件。
然而,随着 records 的引入,我认为这是一个比 Kotlin 提供的更好、更长远的解决方案——尤其是考虑到在这个 Java 语言更新中部分解释的计划(为了了解完整的背景,建议观看整个视频)。
Java 21 的模式匹配具有类型模式和穷尽性,因此这是 Kotlin 目前不再具备的一个优势。
空值处理
在 Java 中,空值一直是一个陷阱。使用有争议的 Optional 类型略有改进。这也是为什么我建议每个人都在任何地方都只使用包装类型,而不是基本类型,除非他们能通过 JMH 测试证明基本类型提供了足够的性能优势。
Kotlin 有所谓的 Elvis 运算符支持,在现代语言设计中,这是处理空值的一种相当流行的选择。这比没有任何东西要好,但它在与语言类型系统的交互中可能显得相当不符合人体工程学和稀奇古怪。我更喜欢一般的单子方法,其中包括广泛建立的 map 和 flat map 约定,而不是在代码中随处添加 ?s。
Java 中 Optional 的最大缺点不是语法的开销,而是围绕它的争议,即是否应该使用它。最初,它几乎专门为 Java 8 Streams 创建,而 JDK 维护人员的“没有人应该使用它”的信条确实是有害的。最近,更多在 Oracle 薪资单上的人已经公开表示,你可以并且应该在任何地方都使用 Optional,而不是冒着 NPE 的风险,主要例子在这里。
我的观点是,他们不希望在野外有巨大的采用和实现,这些实现使用 Optional<?> 类型作为三种可能值(null,Optional.of 和 Optional.empty)的存储,以便整个 Valhalla 值对象项目更容易处理将 Optional 作为内联类型而不允许 null(这将打破所有先前使用 Optional 的代码)。这比潜在地打破野外的代码并坚持认为它们没有遵守 Optional 的 Javadoc 更容易。
其他特性
Kotlin 中的其他特性,如语言语法和方法扩展,并不值得一提。仅仅为了引入特性而引入特性可能会相当有害。最大的警告例子来自前面提到的另一种语言 Scala,它像 C++ 一样提供了在类型上重载运算符的选项。类似的功能会使代码变得难以维护,因为你不能再安全地假设运算符会执行你期望的操作。
最佳的下一个例子是扩展方法。在一个预期每个团队主要由初级、中级,然后是高级成员组成的公司中,这确实很危险。它可能导致大量充满陷阱的糟糕代码,对未经培训的人来说很危险。关于这一点的另一个事项——如果你希望任何人通过入门仪式来维护一段代码——你并不像一位软件工程师。相反——你正在违反软件工程的道德规范!代码必须是可维护的,这是首要指令。
Kotlin 的缺点
Java 代码互操作性
你问第一个优点怎么也能成为缺点?嗯,这里有一篇官方博客文章,清晰地描绘了这个情景。引用一下:
下一步很直接:我们期望 Kotlin 推动 IntelliJ IDEA 的销售。现在你可以想象为什么 IntelliJ IDEA 在所有这些年后有将 Java 转换为 Kotlin 的操作,但没有将 Kotlin 转换为 Java 的操作。这是供应商锁定和提取更大利润的常规做法——这在 2023 年再次变得流行。但我岔开了。
Kotlin 生态系统
与 Java 相比,Kotlin 生态系统严重不足。FAANG (译注:FAANG 是指美国科技行业五家知名公司的首字母缩写,包括 Facebook、Apple、Amazon、Netflix 和 Google。这个术语通常用来指代这些公司在科技和互联网领域的领先地位。)对 Java 提供了一流的支持和承诺,例如提供 JDK,并且在多年的支持方面表现出色。
人才队伍
直到今天,Kotlin 开发人员明显比 Java 开发人员少。这对于使用 Kotlin 的公司来说意味着更昂贵的人才和在项目上找到人才的障碍。他们可以选择等待市场上出现适合的人才,或者开始培训他们的 Java 开发人员使用 Kotlin。这两种选择都需要花费资金。
进展不足
与最近的 Java 相比(例如,两年前的 records、模式匹配和今年的 VT 发布),Kotlin 在提供能够为我们(Infobip)带来价值的重要功能方面一直处于停滞状态。对我来说,这是关于 Kotlin 的最大担忧,超过了迄今为止提到的所有其他问题。
扮演魔鬼的辩护人
事实仍然是我们需要 Kotlin。为什么?为了帮助我们进行研究、创新和挑战现状。如果 Kotlin 继续停滞不前,没有新的有热门功能的竞争对手出现来提高我们的交付效率,这将是一个问题。对于一家半数以上的基础设施,如果不是更多,是用 Java 编写并且仅在 JVM 中运行的公司来说,转向 Kotlin 等替代方案比转向 Rust 或 Go 要便宜得多。我们需要选择,不应该把所有的鸡蛋放在一个篮子里。
黯淡的未来
为了完成本文,这就是标题所指的。在 Infobip,从 2017 年至今一直是 Kotlin 的黄金时代。它是否会继续取决于 JetBrains 及其创新 Kotlin 的能力。关键时刻将是 2025 年。
为什么是 2025 年?在那时,我们将看到更多的功能出现在 Java 中(例如,Valhalla 和 Panama 项目),而 Kotlin 没有替代品。如果 Kotlin 到那时没有取得重大突破,它的受欢迎程度将下降并达到一个临界点。你已经可以在 YouTube、Hacker News 或 Reddit 等开发者社区中看到情绪朝着这个方向发展,但目前还不是关键时刻。