제이온

[Effective Java] Mục 2: Cân nhắc sử dụng Builder khi Constructor có nhiều tham số

  • Ngôn ngữ viết: Tiếng Hàn Quốc
  • Quốc gia: Tất cả các quốc giacountry-flag
  • CNTT

Đã viết: 2024-04-27

Đã viết: 2024-04-27 00:46

Mô hình Builder theo cấp bậc

Cả hàm tạo tĩnh và hàm tạo đều khó xử lý khi có quá nhiều tham số. Ví dụ, nếu lớp có 6 trường và bạn muốn tạo hàm tạo khi có 2 tham số, 3 tham số,... thì có thể sử dụng mô hình Builder theo cấp bậc như sau.



Tuy nhiên, ngay cả khi sử dụng cách này, nếu số lượng tham số tăng lên, việc đọc mã sẽ trở nên khó khăn hơn khi không biết ý nghĩa của từng giá trị và có thể nhầm lẫn giữa các tham số có cùng kiểu dữ liệu.


Mô hình JavaBeans

Mô hình JavaBeans tạo ra đối tượng bằng hàm tạo không tham số, sau đó gọi các phương thức setter để thiết lập giá trị cho các tham số mong muốn.



Mô hình JavaBeans cho phép tạo đối tượng mà không cần lo lắng về việc nhầm lẫn các tham số khi số lượng tham số tăng lên. Tuy nhiên, để tạo ra một đối tượng, bạn cần gọi nhiều phương thức setter, và tính nhất quán của đối tượng có thể bị phá vỡ trước khi nó được hoàn thiện. Do đó, lớp không thể được thiết kế là bất biến.


Mô hình Builder

Mô hình Builder thường được sử dụng vì nó kết hợp sự ổn định của mô hình Builder theo cấp bậc và khả năng đọc của mô hình JavaBeans.

Thay vì tự tạo đối tượng, khách hàng sẽ gọi hàm tạo với chỉ các tham số bắt buộc để lấy đối tượng Builder. Sau đó, khách hàng sẽ sử dụng các phương thức setter (một dạng) do đối tượng Builder cung cấp để thiết lập các tham số tùy chọn. Cuối cùng, khách hàng sẽ gọi phương thức build() không tham số để lấy đối tượng cần thiết.



Lớp Builder có hàm tạo nhận các tham số bắt buộc, và các tham số tùy chọn khác được thiết lập bằng các phương thức setter. Cuối cùng, phương thức build() được gọi để tạo ra đối tượng NutritionFactsWithBuilderPattern hoàn chỉnh. Lớp NutritionFactsWithBuilderPattern là bất biến, và các phương thức setter của Builder trả về chính Builder, cho phép chúng được gọi liên tiếp. Cách này được gọi là API trôi chảy hoặc phương thức liên tiếp.



Đối với khách hàng, mô hình Builder giúp viết và đọc mã dễ dàng hơn.


Mô hình Builder phù hợp với các lớp được thiết kế theo phân cấp


Lớp Pizza.Builder là kiểu dữ liệu chung sử dụng giới hạn kiểu đệ quy, và thêm phương thức trừu tượng self() để các lớp con có thể hỗ trợ phương thức liên tiếp mà không cần ép kiểu. Trong các lớp con, chỉ cần trả về chính nó cho phương thức trừu tượng này.

Bây giờ, hãy xem xét Pizza New York và Pizza Calzone, các lớp con của Pizza, để trải nghiệm sự linh hoạt của mô hình Builder.



Hàm tạo build() được định nghĩa trong lớp Builder của mỗi lớp con trả về lớp con cụ thể. Khả năng các phương thức trong lớp con trả về kiểu con của kiểu được trả về bởi phương thức trong lớp cha được gọi là ép kiểu trả về đồng biến. Nhờ tính năng này, khách hàng không cần ép kiểu.



Khách hàng có thể kết hợp các enum của Pizza và các enum của mỗi lớp con, và có thể hoàn thiện đối tượng bằng các phương thức phù hợp tương ứng.


Nhược điểm của mô hình Builder

  • Cần tạo đối tượng Builder.
  • Mã nguồn dài dòng.


Tóm tắt

Nếu hàm tạo hoặc phương thức tạo tĩnh phải xử lý quá nhiều tham số, hãy cân nhắc sử dụng mô hình Builder.


Nguồn tham khảo

  • Effective Java

Bình luận0