0
0
Lập trình
Flame Kris
Flame Krisbacodekiller

Mẫu Thiết Kế Builder trong Java: Giải Pháp Sạch sẽ!

Đăng vào 1 tháng trước

• 6 phút đọc

Giới thiệu

Khi thiết kế các đối tượng phức tạp trong Java, đặc biệt là những đối tượng có nhiều tham số tùy chọn, Mẫu Thiết Kế Builder cung cấp một giải pháp sạch sẽ và linh hoạt. Thay vì sử dụng các hàm khởi tạo dài với hàng chục tham số (thường được gọi là vấn đề hàm khởi tạo dài), mẫu Builder giúp chúng ta tạo ra các đối tượng từng bước một cách dễ đọc.

  • Trong bài viết này, chúng ta sẽ tìm hiểu:
    • Vấn đề với việc tạo đối tượng truyền thống.
    • Cách hoạt động của Mẫu Thiết Kế Builder.
    • Một triển khai thực tế trong Java.
    • Ưu điểm và các trường hợp sử dụng.

Vấn đề

Hãy tưởng tượng bạn đang xây dựng một lớp User với nhiều trường:

java Copy
public class User {
    private String firstName;
    private String middleName;
    private String lastName;
    private int age;
    private String email;
    private String phone;
    private String alternativePhone;
}

Bây giờ, hãy xem xét các kịch bản cho người dùng:

  • Một người dùng chỉ có tên và họ mà không có tên đệm.
  • Một người dùng không có số điện thoại thay thế.
  • Một người dùng với tất cả các trường.

Nếu bạn cố gắng xử lý điều này bằng cách sử dụng các hàm khởi tạo, bạn sẽ kết thúc với nhiều hàm khởi tạo quá tải như:

java Copy
User(String firstName, String lastName) { ... }
User(String firstName, String middleName, String lastName) { ... }
User(String firstName, String lastName, int age, String email, String phone) { ... }
User(String firstName, String lastName, int age, String email, String phone, String alternativePhone) { ... }

Cách tiếp cận này nhanh chóng trở nên lộn xộn và khó đọc.


Giải pháp: Mẫu Builder

Mẫu Builder tách biệt việc xây dựng một đối tượng phức tạp khỏi việc biểu diễn của nó, cho phép bạn tạo ra các đối tượng từng bước một.

java Copy
public class User {
    // Các trường bắt buộc
    private final String firstName;
    private final String lastName;
    private final int age;
    private final String email;
    private final String phone;

    // Các trường tùy chọn
    private final String middleName;
    private final String alternativePhone;

    // Hàm khởi tạo riêng để đảm bảo việc tạo đối tượng thông qua Builder
    private User(Builder builder) {
        this.firstName = builder.firstName;
        this.lastName  = builder.lastName;
        this.middleName  = builder.middleName;
        this.age       = builder.age;
        this.email     = builder.email;
        this.phone     = builder.phone;
        this.alternativePhone = builder.alternativePhone;
    }

    // Lớp Builder lồng vào
    public static class Builder {
        private final String firstName;
        private final String lastName;
        private int age;
        private String email;
        private String phone;
        private String alternativePhone;

        // Hàm khởi tạo Builder với các trường bắt buộc
        public Builder(String firstName, String lastName, int age, String email, String phone) {
            this.firstName = firstName;
            this.lastName  = lastName;
            this.age = age;
            this.email = email;
            this.phone = phone;
        }

        // Các phương thức giống như setter cho các trường tùy chọn
        public Builder middleName(String middleName) {
            this.middleName = middleName;
            return this;
        }

        public Builder alternativePhone(String alternativePhone) {
            this.alternativePhone = alternativePhone;
            return this;
        }

        // Phương thức build cuối cùng
        public User build() {
            return new User(this);
        }
    }

    @Override
    public String toString() {
        return "User [firstName=" + firstName + ", lastName=" + lastName + ", middleName=" + middleName + ", age=" + age + ", email=" + email + ", phone=" + phone + ", alternativePhone=" + alternativePhone + "]";
    }
}

Cách sử dụng:

java Copy
public class Main {
    public static void main(String[] args) {
        User user1 = new User.Builder("John", "Doe", 30, "john.doe@example.com", "1234567890")
                          .middleName("Mario")
                          .build();

        User user2 = new User.Builder("Alice", "Smith", 25, "alice@example.com", "1234567890")
                          .alternativePhone("4365354633")
                          .build();

        System.out.println(user1);
        System.out.println(user2);
    }
}

Kết quả

Copy
User [firstName=John, middleName=Mario, lastName=Doe, age=30, email=john.doe@example.com, phone=1234567890, alternativePhone=null]
User [firstName=Alice, middleName=null, lastName=Smith, age=25, email=alice@example.com, phone=1234567890, alternativePhone=4365354633]

Ưu điểm của Mẫu Builder

✔️ Giúp việc xây dựng đối tượng trở nên dễ đọc và duy trì.
✔️ Xử lý các tham số tùy chọn một cách hợp lý.
✔️ Thúc đẩy tính bất biến (các đối tượng được tạo ra là không thay đổi).
✔️ Cung cấp phương pháp từng bước để xây dựng các đối tượng.

Khi nào nên sử dụng?

  • Khi bạn có một lớp với nhiều tham số tùy chọn.
  • Khi các hàm khởi tạo với nhiều tham số trở nên khó hiểu.
  • Khi bạn muốn tạo các đối tượng bất biến một cách sạch sẽ.

Ví dụ thực tế

  • StringBuilder trong Java (để xây dựng chuỗi từng bước).
  • DocumentBuilder trong phân tích XML.
  • Nhiều framework như Lombok, Jackson, và Spring sử dụng các builder nội bộ.

Kết luận

Mẫu Thiết Kế Builder là một trong những mẫu thiết kế sáng tạo mạnh mẽ và thường được sử dụng trong Java. Nó giúp mã nguồn trở nên dễ đọc, mở rộng và duy trì, đặc biệt là khi làm việc với các đối tượng phức tạp có thuộc tính tùy chọn.

Lần tới khi bạn thấy mình viết nhiều hàm khởi tạo hoặc gặp khó khăn với các tham số tùy chọn, hãy nghĩ đến Mẫu Builder!


Đây là Phần 5 trong chuỗi Mẫu Thiết Kế Java.

Nếu bạn thấy bài viết này hữu ích, hãy cho tôi biết ý kiến của bạn. Cũng cho tôi biết nếu bạn đã sử dụng mẫu builder trong các dự án của mình.

Chương tiếp theo: Mẫu Thiết Kế Cấu Trúc!

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào