何时使用面向数据编程 v1.1
Nicolai Parlog 于 2024 年 6 月 10 日在本系列关于面向数据编程 v1.1 的第六篇也是最后一篇文章中,我们将对面向数据编程 (DOP) 与函数式编程 (FP) 和面向对象编程 (OOP) 进行回顾。首先,让我们简要总结一下这四项指导原则给我们留下了什么
- 使用类型来表示数据
- 以透明且不可变的方式建模数据(通常使用记录)。
- 使用密封接口建模备选方案。
- 尽可能接近地建模数据,并且只表示合法状态。
- 将操作实现为其他类上的方法
- 使用详尽的
switch
语句,主要用于密封接口,并且没有default
分支。 - 使用模式匹配来识别和分解数据。
- 使用详尽的
如果您想详细了解,请在此处查找其他文章
- Java 中的面向数据编程 - 版本 1.1
- 以不可变且透明的方式建模数据 - DOP v1.1
- 建模数据,全部数据,仅此而已 - DOP v1.1
- 使非法状态不可表示 - DOP v1.1
- 将操作与数据分离 - DOP v1.1
- 总结 DOP v1.1(本文)
- 附录:为什么要将 DOP 更新到版本 1.1?
您需要哪个 Java 版本?
在我们深入了解 DOP 以及它与 FP 和 OOP 的比较之前,让我们简要介绍一下它在哪些 Java 版本上效果最好。虽然记录和密封类型存在于 JDK 17 中,但 switch
中同样重要的模式直到 JDK 21 才最终确定,这使得它成为面向数据编程的最低要求。
单个下划线作为未命名的模式在 JDK 22 中最终确定,虽然它非常有用且优雅,但它不是必需的。它的缺失可以通过重复“默认”分支来解决(记住,避免完全使用默认分支!)。
switch(item) {
case Book book -> createTableOfContents(book);
case Furniture unused -> { }
case ElectronicItem unused -> { }
}
DOP 与 FP 和 OOP 的比较
在函数式编程中,所有操作都是纯函数,它们以数据作为输入和输出,并且不会产生任何副作用 - 适当组合后,它们实现了系统的逻辑。如果您将系统的所有可变部分集中在专用子系统中(例如,客户端中的用户界面和数据库中的数据存储),并将系统的无状态剩余部分视为在其他子系统之间进行调解的函数(例如,用户输入和数据库的当前状态映射到更改界面和数据库的指令),这将有效。这种方法对于 Web 应用程序特别有效,并且可以导致非常易于维护的代码。
然而,在许多项目中,事实证明很难实现或维护这种绝对的无状态性和没有副作用。从团队在函数式编程方面的经验到语言的适用性,从功能和性能要求到支持这种方法的库和框架的可用性,挑战比比皆是。
函数式编程的优势不是遵循所有规则后等待您的灵丹妙药,而是它的方法即使在小规模上也能很好地工作。任何以函数形式表示的领域逻辑 - 无论是简单的流管道还是一系列手写函数 - 都使代码库更可靠,通常也更易于维护。
面向数据编程利用了这一事实,并提出了一种结构,该结构尽可能地有利于函数式纯度,并将必要的偏差尽可能地隔离在负责相应逻辑的子系统中。因此,DOP 介于 FP 和 OOP 之间,但总体上更接近前者。
但面向对象编程并没有消亡(再次)。封装和继承的工具,将大型问题模块化(即分解成彼此大部分隔离的小问题)的简便性,以及我们对这种编程范式的熟悉,使其仍然具有价值。因此,我无意推荐从 OOP 到 DOP(或 FP)的根本性转变。相反,我们应该将 DOP 视为一种可以在适当情况下应用的额外工具。
何时使用 DOP
与函数式编程类似,面向数据编程的优势即使在小规模上也能感受到。记录的使用,防止变异,避免在数据上放置复杂操作,switch
相对于访问者模式的清晰度 - 任何在正确环境中使用这些技术的代码片段都将比没有它们更清晰,更易于维护。因此,没有必要以面向数据的方式开发整个系统。
如果您想从小规模开始,您应该注意两种情况
- 数据处理(子)系统
- 不需要进一步模块化的小型(部分)问题
例如,直接摄取和输出数据的系统(例如批处理作业或数据分析工具)、处理事件(事件将是“数据”)或建模现有结构以允许其操作(结构将是“数据”,操作将通过函数式转换实现 - 例如,请参见 JEP 457 中的新类文件 API)非常适合。这可以是一个小型独立服务,也可以是大型系统的一部分。
根据我自己的经验,我可以说:一旦您使用过面向数据编程并在实践中体验过这些概念,您很快就会开始在各个地方看到大小不一的用例,到目前为止,我对结果一直非常满意。由于数据和操作的分离,代码可读性很高,两者都可以轻松地单独验证和测试,并且整体架构易于理解。
对于所有在这次(彻底的)介绍后变得好奇,并且很快将使用 DOP 的人:祝您好运,玩得开心!🍀