Java 中的 DTO 与 Record:比较 DTO 和 Record

Java 中的 DTO 与 Record:有啥区别,具体如何选择?

Java 中的 DTO 与 Record:什么是 Java Record?

Java 中的 DTO 与 Record:比较 DTO 和 Record

目前我们已经了解了 DTO 和 Record,接下来在这一节中进行比较。

(1)不可变性

Record 默认是不可变的,这意味着一旦创建了一个 Record 实例,你就无法更改其数据。这种不可变性确保了数据的一致性和线程安全性,无需额外的代码。例如,在一个 UserRecord 中,字段 name、age 和 email 只能在创建 Record 时设置,之后无法修改。

另一方面,DTO 一般是可变的,这意味着它们的字段可以在对象创建后更改。要使 DTO 不可变,你需要明确避免使用 setter 或精心设计它们(例如,使用 final 字段)。以下是 Record 与传统 DTO 在不可变性方面的对比:

  • Record:默认不可变。
  • DTO:需要手动强制实现不可变性,这可能导致代码更加复杂并引发潜在的错误。

public class ImmutabilityExample {
 public static void main(String[] args) {
 UserDTO userDTO = new UserDTO("xxx", 25, "xxx@example.com");
 userDTO.setAge(26); // DTO allows this by default.

 UserRecord userRecord = new UserRecord("xxx", 25, "xxx@example.com");
 userRecord.name = "Jane"; // This would result in a compile-time error.
 }
}

(2)数据表明

Record 提供了一种 简洁且紧凑 的数据表明方式。由于 Record 的声明只包含字段,代码更加清晰易读。这使得在拥有大量数据模型的项目中维护代码变得更加容易。

例如:

// Record:简洁明了
public record UserRecord(String name, int age, String email) {}

与之相比,DTO 一般包含更多的代码:

// DTO:更加冗长
public class UserDTO {
 private String name;
 private int age;
 private String email;
 // 构造函数、Getter、Setter、toString、equals、hashCode...
}

使用 Record,意图更加明确:它只是一个数据载体,没有额外的行为,而 DTO 则容易被样板代码或额外逻辑所充斥。

(3)定制化

在定制化方面,DTO 有必定的优势。DTO 允许你添加自定义逻辑,例如数据验证、转换方法,甚至在需要时添加业务逻辑(尽管在纯 DTO 中一般不推荐)。例如,你可以添加一个验证方法来确保电子邮件字段符合有效格式。

而 Record 的自定义能力则较为有限。由于它们被设计为轻量级且不可变的,因此你无法轻松地添加修改内部状态或执行复杂逻辑的自定义方法。如果你的用例需要在数据对象中包含自定义行为或逻辑,DTO 提供了更多的灵活性。

以下是一个在 DTO 中添加自定义验证的示例:

public class UserDTO {
 private String email;
 // 验证电子邮件格式的方法
 public boolean isValidEmail() {
 return email != null && email.contains("@");
 }
}

对于 Record,这种级别的自定义一般需要在 Record 之外进行处理。Record 专注于携带数据,而像验证这样的逻辑一般需要在其他地方处理。

(4)与函数式编程的一致性

函数式编程的一个核心原则是不可变性——即数据对象在创建后不应被修改。Record 更加符合函数式编程的原则,由于它们默认是不可变的。这使得它们成为采用或倾向于函数式编程风格的系统的理想选择。

Record:

  • 被设计为不可变的,这与函数式编程强调创建不可变数据结构的理念相一致。
  • 它们促进了更具声明性的风格,你可以传递不可变的数据对象,而不会产生副作用,这使得它们更加可预测且易于理解。

相比之下,DTO 本质上是可变的。尽管可以通过避免使用 setter 和使用 final 字段来使 DTO 不可变,但这需要手动强制执行。DTO 一般遵循 面向对象 的范式,其中状态变化更为常见。

DTO:

  • 在可变性方面更加灵活,这使得它们更适合命令式或面向对象的编程风格。
  • 当以可变形式使用时,DTO 可能会导致副作用,这在函数式编程中一般是不被推荐的。

#夏日生活打卡季##上头条 聊热点##java##record##Java##JDK#

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 共1条

请登录后发表评论