Bài viết này chia sẻ sự khác biệt giữa class + Lombok annotation với record. Record là một từ khoá mới xuất hiện từ JDK 16.

Bất kỳ ai đã lập trinh Spring Boot đều biết thư viện Lombok. Lombok giúp cho lập trình viên không phải viết những đoạn code lặp đi lặp lại (Boilerplate code)

public class Book {
private String id;
private String title;
private List<String> authors;
private int pages;
public Book(String id, String title, List<String> authors, int pages) {
    this.id = id;
    this.title = title;
    this.authors = authors;
    this.pages = pages;
}
public String getId() {
    return id;
}
public void setId(String id) {
    this.id = id;
}
public String getTitle() {
    return title;
}
public void setTitle(String title) {
    this.title = title;
}
public List<String> getAuthors() {
    return authors;
}
public void setAuthors(List<String> authors) {
    this.authors = authors;
}
public int getPages() {
    return pages;
}
public void setPages(int pages) {
    this.pages = pages;
}
}

Lombok xuất hiện mọi thứ trở nên gọn gàng hơn nhiều

import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Book {
private String id;
private String title;
private List<String> authors;
private int pages;
}

@Data

Annotation này chỉ áp dụng cho class và trong lúc lập trình, sửa đổi mã nguồn RetentionPolicy.SOURCE

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)

@Data sẽ sinh mã nguồn các phương thức getter, setter, toString, equals, hashCode

@AllArgsConstructor

Sinh ra constructor chưa đầy đủ các tham số tương ứng với thuộc tính của class

@NoArgsConstructor

Sinh ra default constructor không chứa bất kỳ tham số nào.

@Builder

Cho phép bạn tạo đối tượng bằng cách khởi tạo từng thuộc tính qua các hàm nối chuỗi lại với nhau

Book book = Book.builder()
.id("OX-13")
.title("Những người thích đùa")
.authors(List.of("Axit Nezin"))
.pages(125)
.build();

record có thay thế cho class hay Lombok không?

record là một từ khoá mới xuất hiện từ Java JDK 16. Mục đích của record là tạo ra một Immutable Plain Old Java Object. Để tôi giải thích nhé

  • Immutable: có nghĩa là khởi tạo xong, không thể thay đổi được thuộc tính
  • Plain Old Java Object (POJO): đối tượng Java đơn giản, cổ điển, không có bổ xung thêm các annotation. POJO sẽ khác với đối tượng Java đánh dấu bởi @Entity trong JPA hay @Controller để tạo thành bean. POJO sinh ra để làm nhiệm vụ đóng gói các thuộc tính dữ liệu để truyền qua lại.

Nếu như class thông thường, chúng ta có phương thức getter và setter. Nhưng record sẽ chỉ có phương thức getter, ngoài ra bạn vẫn có thể viết thêm các phương thức khác vào record. Như vậy chúng ta chỉ có thể truyền tham số vào record tại thời điểm khởi tạo bằng constructor. record đảm bảo rằng trong quá trình truyền qua lại (passing) sẽ không cho phép code sửa đổi nội dung thuộc tính bên trong. record sẽ rất thích hợp với môi trường lập trình concurreny, multi-thread. Nếu bạn đã từng nghe pattern Event Sourcing thì các bạn sẽ thấy ý nghĩa của việc tạo ra các bản ghi không được sửa đổi. Muốn sửa đổi thì tạo bản ghi mới. Việc này giúp chúng ta lưu lại lịch sử thay đổi chứ không chỉ lưu trạng thái cuối cùng.

Dùng record khi nào?

record chỉ nên dùng khi đóng gói, truyền dữ liệu qua lại, data transfer object… record không thể dùng để mô hình Entity trong JPA.

Bạn cứ mạnh dạn dùng record chớ có ngại là nó còn quá mới, chưa ổn định. Người ta đã chạy kiểm thử chán chê qua nhiều năm, trải qua nhiều phiên bản preview rồi mới release tính năng này. Và thực sự record có ý nghĩa cụ thể trong lập trình đó bạn nhé.