POJO và JavaBean khác nhau như thế nào?

Trong bài viết này chúng ta sẽ cùng nhau tìm hiểu POJO (Plain Old Java Object) trong Java, sau đó chúng ta sẽ tiến hành so sánh POJO với JavaBean và tại sao JavaBean được khuyến khích sử dụng hơn.

Plain Old Java Object 

POJO là gì

Khi chúng ta nói về POJO nó chỉ đơn giản một class không chịu sự chi phối của bất kỳ một framework cụ thể nào. Một POJO không có một quy tắc đặt tên cụ thể nào cho các thuộc tính và method của nó.

Giả sử chúng ta có một EmployeePojo class với 3 thuộc tính firstname, lastname và startdate.

public class EmployeePojo {

    public String firstName;
    public String lastName;
    private LocalDate startDate;

    public EmployeePojo(String firstName, String lastName, LocalDate startDate) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.startDate = startDate;
    }

    public String name() {
        return this.firstName + " " + this.lastName;
    }

    public LocalDate getStart() {
        return this.startDate;
    }
}

EmployeePojo có thể sử dụng ở bất kỳ một chương trình, framework nào. Nhưng nó thật sự không có một quy tắc nào để định nghĩa constructor, class state, modifier (public, private, protected, default). Do vậy EmployeePojo class có thể gặp một số rắc rối khi sử dụng trong các framework. Chúng ta sẽ làm rõ vấn đề này thông qua việc sử dụng reflection trên EmployeePojo.

POJO Reflection

Trước tiên, để thao tác reflection trên EmployeePojo chúng ta cần thêm commons-beanutils dependency vào project maven:

<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.9.4</version>
</dependency>

Bây giờ mình sẽ sử dụng reflection để in tên các thuộc tính trong EmployeePojo ra màn hình console.

import org.apache.commons.beanutils.PropertyUtils;

import java.beans.PropertyDescriptor;

public class Main {
    public static void main(String... args) {
        PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(EmployeePojo.class);
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            System.out.println(propertyDescriptor.getDisplayName());
        }
    }
}

Output: 

start

Như chúng ta thấy rằng PropertyUtils đã không thể tìm thấy 2 thuộc tính còn lại của EmployeePojo class. Chúng ta cũng sẽ gặp điều tương tự nếu sử dụng Jackson để xử lý EmployeePojo class. 

Nếu không thể tìm thấy được 2 thuộc tính firstname và lastname trong EmployeePojo thì quả thật đó là một vấn đề lớn khi các framework xử lý bằng phương pháp reflection. May mắn thay hầu hết các thư viện của Java đều hỗ trợ các Java class tuân thủ một quy tắc đặt tên được gọi là JavaBean.

JavaBean

JavaBean là gì

JavaBean trên thực thế vẫn là một POJO nhưng nó tuân thủ các quy tắc sau:

  • Access levels: các thuộc tính trong class đều được đặt là private và chúng chỉ được truy xuất thông qua getter, setter method.
  • Method name: getter và setter method tuân thủ theo quy tắc getX và setX (X là tên thuộc tính). Trong trường hợp thuộc tính có kiểu dữ liệu boolean thì có thể đặt là isX.
  • Default Constructor: Luôn tồn tại một constructor mặc định không chứa tham số đầu vào.
  • Serializable: implement Serializable interface.

Định nghĩa JavaBean

Trong phần này chúng ta sẽ cố gắng chuyển EmployeePojo sang JavaBean

import java.io.Serializable;
import java.time.LocalDate;

public class EmployeeBean implements Serializable {

    private static final long serialVersionUID = -3760445487636086034L;
    private String firstName;
    private String lastName;
    private LocalDate startDate;

    public EmployeeBean() {
    }

    public EmployeeBean(String firstName, String lastName, LocalDate startDate) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.startDate = startDate;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public LocalDate getStartDate() {
        return startDate;
    }

    public void setStartDate(LocalDate startDate) {
        this.startDate = startDate;
    }
}

Và giờ chúng ta sẽ thử sử dụng reflection để tìm kiếm các thuộc tính trong EmployeeBean.

import org.apache.commons.beanutils.PropertyUtils;

import java.beans.PropertyDescriptor;

public class Main {
    public static void main(String... args) {
        PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(EmployeeBean.class);
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            System.out.println(propertyDescriptor.getDisplayName());
        }
    }
}

Output

firstName
lastName
startDate

Một số hạn chế khi sử dụng JavaBean

JavaBean có thể hữu dụng khi sử dụng trong các framework ngày nay, tuy nhiên việc sử dụng nó cũng có một số hạn chế nhất định mà chúng ta sẽ phải chấp nhận:

  • Mutability: các JavaBean sẽ không thể đạt được tính chất immutable vì chúng phải định nghĩa các setter method.
  • Boilerplate: Việc triển khai getter, setter method cho toàn bộ các thuộc tính trong class đôi khi không cần thiết.
  • No -Agrs Constructor: Chúng ta thường không cung cấp no-args constructor vì có một số thuộc tính bắt buộc phải có giá trị sau khi khởi tạo, chúng ta sẽ không thể đặt được mục đích này khi sử dụng JavaBean.

Tóm lược

Qua bài biết này chúng ta đã tìm hiểu được POJO và JavaBean là gì. Trong khi JavaBean gần như được sử dụng nhiều hơn vì sự phát triển của rất nhiều các framework nổi tiếng của Java giúp chúng ta phát triển ứng dụng nhanh hơn, tuy nhiên có một số hạn chế của JavaBean mà chúng ta phải chấp nhận để tương thích với các framework đang sử dụng.

Nguồn

https://www.baeldung.com/java-pojo-class

5 1 vote
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x