Hôm nay, chúng ta sẽ tìm hiểu về Builder Design Pattern trong Java (mẫu thiết kế Builder). Đây là một mẫu dạng khởi tạo (creational), tương tự như các mẫu Factory và Abstract.
Mẫu này ra đời nhằm giải quyết một số vấn đề của Factory và Abstract, đặc biệt khi một đối tượng chứa nhiều thuộc tính. Có ba vấn đề chính thường gặp với các mẫu thiết kế trong trường hợp đối tượng có nhiều thuộc tính:
Phải truyền quá nhiều tham số từ chương trình client đến class Factory. Điều này dễ gây ra lỗi vì kiểu dữ liệu của các tham số thường giống nhau, khiến phía client khó đảm bảo đúng thứ tự của chúng.
Một số tham số có thể là không bắt buộc (optional), nhưng với Factory pattern, ta vẫn phải truyền vào đầy đủ. Đối với các tham số không bắt buộc này, ta phải truyền giá trị NULL.
Nếu việc khởi tạo một object phức tạp và tốn nhiều tài nguyên, toàn bộ logic phức tạp đó sẽ nằm trong các class Factory, khiến chúng trở nên rối rắm và khó hiểu.
Ta có thể giải quyết vấn đề số lượng tham số lớn bằng cách cung cấp một constructor (phương thức khởi tạo) chỉ chứa các tham số bắt buộc, sau đó dùng các phương thức setter (phương thức gán giá trị cho thuộc tính) để gán giá trị cho các tham số tùy chọn. Tuy nhiên, vấn đề của cách tiếp cận này là trạng thái của đối tượng sẽ không nhất quán cho đến khi tất cả các thuộc tính được thiết lập một cách tường minh.
Mẫu Builder giải quyết vấn đề với số lượng lớn tham số tùy chọn và trạng thái không nhất quán bằng cách cung cấp một phương pháp xây dựng đối tượng theo từng bước, và cuối cùng sẽ cung cấp một phương thức để trả về đối tượng hoàn chỉnh.
Mẫu thiết kế Builder trong Java
Hãy cùng xem cách triển khai Builder pattern trong Java.
Đầu tiên, ta cần tạo một lớp static lồng nhau (nested) rồi sao chép tất cả các thuộc tính từ lớp bên ngoài vào lớp Builder này. Ta nên tuân theo quy ước đặt tên: nếu lớp chính tên là Computer, thì lớp builder nên có tên là ComputerBuilder.
Lớp Builder trong Java nên có một constructor dạng public với các tham số là những thuộc tính bắt buộc.
Lớp Builder trong Java nên có các phương thức để thiết lập những tham số tùy chọn. Mỗi phương thức này sau khi gán giá trị xong sẽ trả về chính đối tượng Builder đó.
Bước cuối cùng là cung cấp một phương thức build() trong lớp builder để trả về đối tượng mà chương trình client cần. Để làm được điều này, lớp chính cần có một constructor dạng private và nhận chính lớp Builder làm tham số.
Dưới đây là một chương trình ví dụ có lớp Computer cùng với lớp ComputerBuilder để tạo ra nó.
package com.journaldev.design.builder;
public class Computer {
//required parameters
private String HDD;
private String RAM;
//optional parameters
private boolean isGraphicsCardEnabled;
private boolean isBluetoothEnabled;
public String getHDD() {
return HDD;
}
public String getRAM() {
return RAM;
}
public boolean isGraphicsCardEnabled() {
return isGraphicsCardEnabled;
}
public boolean isBluetoothEnabled() {
return isBluetoothEnabled;
}
private Computer(ComputerBuilder builder) {
this.HDD=builder.HDD;
this.RAM=builder.RAM;
this.isGraphicsCardEnabled=builder.isGraphicsCardEnabled;
this.isBluetoothEnabled=builder.isBluetoothEnabled;
}
//Builder Class
public static class ComputerBuilder{
// required parameters
private String HDD;
private String RAM;
// optional parameters
private boolean isGraphicsCardEnabled;
private boolean isBluetoothEnabled;
public ComputerBuilder(String hdd, String ram){
this.HDD=hdd;
this.RAM=ram;
}
public ComputerBuilder setGraphicsCardEnabled(boolean isGraphicsCardEnabled) {
this.isGraphicsCardEnabled = isGraphicsCardEnabled;
return this;
}
public ComputerBuilder setBluetoothEnabled(boolean isBluetoothEnabled) {
this.isBluetoothEnabled = isBluetoothEnabled;
return this;
}
public Computer build(){
return new Computer(this);
}
}
}
Lưu ý rằng lớp Computer chỉ có các phương thức getter (lấy tham số) và không có constructor dạng public. Vì vậy, cách duy nhất để có được một đối tượng Computer là thông qua lớp ComputerBuilder.
Dưới đây là một chương trình mẫu cho thấy cách sử dụng lớp Builder để lấy đối tượng.
package com.journaldev.design.test;
import com.journaldev.design.builder.Computer;
public class TestBuilderPattern {
public static void main(String[] args) {
//Using builder to get the object in a single line of code and
//without any inconsistent state or arguments management issues
Computer comp = new Computer.ComputerBuilder(
"500 GB", "2 GB").setBluetoothEnabled(true)
.setGraphicsCardEnabled(true).build();
}
}
Ví dụ về mẫu Builder trong JDK
Một số class của Java sử dụng mẫu thiết kế Builder bao gồm:
java.lang.StringBuilder#append() (không đồng bộ)
java.lang.StringBuffer#append() (đồng bộ)
Tổng kết
Hy vọng bài viết đã giúp bạn hiểu rõ hơn về cách áp dụng Builder Design Pattern trong Java để xây dựng các đối tượng phức tạp một cách hiệu quả và an toàn. Nếu bạn có thắc mắc hay cần giải thích thêm về bất kỳ phần nào, đừng ngần ngại đặt câu hỏi bên dưới nhé.
Về tác giả
Bao TranWeb Developer
I’m passionate about web development and sharing my insights through articles, with over 8 years of experience. I hope these sharings inspire you and help build a strong web development community.
@#@
Tôi đam mê phát triển web và chia sẻ những hiểu biết của mình thông qua các bài viết, với hơn 8 năm kinh nghiệm. Tôi hy vọng những chia sẻ này sẽ truyền cảm hứng cho các bạn và giúp xây dựng một cộng đồng phát triển web mạnh mẽ.
Cập nhật thông tin mới nhấtNhận các thông tin mới nhất về mối đe dọa, báo cáo an ninh mạng từ CyStack về hòm thư điện tử của bạn
Thảo luận (0)
Đăng nhập để thảo luận
Bài viết liên quan
{"success":true,"head":"<title>Builder Design Pattern trong Java - CyStack Tutorial</title>\n<meta name=\"description\" content=\"Đọc bài viết này để biết cách sử dụng Builder design pattern trong Java, hỗ trợ tạo các đối tượng có nhiều thuộc tính tùy chọn mà không cần phải truyền đầy đủ hoặc tạo constructor dài dòng.\"/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-video-preview:-1, max-image-preview:large\"/>\n<link rel=\"canonical\" href=\"https://blog.cystack.org/tutorial/2025/07/16/builder-design-pattern-trong-java/\" />\n<meta property=\"og:locale\" content=\"en_US\" />\n<meta property=\"og:type\" content=\"article\" />\n<meta property=\"og:title\" content=\"Builder Design Pattern trong Java - CyStack Tutorial\" />\n<meta property=\"og:description\" content=\"Đọc bài viết này để biết cách sử dụng Builder design pattern trong Java, hỗ trợ tạo các đối tượng có nhiều thuộc tính tùy chọn mà không cần phải truyền đầy đủ hoặc tạo constructor dài dòng.\" />\n<meta property=\"og:url\" content=\"https://blog.cystack.org/tutorial/2025/07/16/builder-design-pattern-trong-java/\" />\n<meta property=\"og:site_name\" content=\"CyStack Tutorial\" />\n<meta property=\"article:tag\" content=\"vi\" />\n<meta property=\"article:section\" content=\"Java\" />\n<meta property=\"og:updated_time\" content=\"2025-07-16T14:44:31+07:00\" />\n<meta property=\"og:image\" content=\"https://s2.cystack.net/tutorial/16144251/builder-design-pattern-trong-java.jpg\" />\n<meta property=\"og:image:secure_url\" content=\"https://s2.cystack.net/tutorial/16144251/builder-design-pattern-trong-java.jpg\" />\n<meta property=\"og:image:width\" content=\"1200\" />\n<meta property=\"og:image:height\" content=\"630\" />\n<meta property=\"og:image:alt\" content=\"Builder Design Pattern trong Java\" />\n<meta property=\"og:image:type\" content=\"image/jpeg\" />\n<meta property=\"article:published_time\" content=\"2025-07-16T14:43:59+07:00\" />\n<meta property=\"article:modified_time\" content=\"2025-07-16T14:44:31+07:00\" />\n<meta name=\"twitter:card\" content=\"summary_large_image\" />\n<meta name=\"twitter:title\" content=\"Builder Design Pattern trong Java - CyStack Tutorial\" />\n<meta name=\"twitter:description\" content=\"Đọc bài viết này để biết cách sử dụng Builder design pattern trong Java, hỗ trợ tạo các đối tượng có nhiều thuộc tính tùy chọn mà không cần phải truyền đầy đủ hoặc tạo constructor dài dòng.\" />\n<meta name=\"twitter:image\" content=\"https://s2.cystack.net/tutorial/16144251/builder-design-pattern-trong-java.jpg\" />\n<meta name=\"twitter:label1\" content=\"Written by\" />\n<meta name=\"twitter:data1\" content=\"Bao Tran\" />\n<meta name=\"twitter:label2\" content=\"Time to read\" />\n<meta name=\"twitter:data2\" content=\"4 minutes\" />\n<script type=\"application/ld+json\" class=\"rank-math-schema\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https://blog.cystack.org/tutorial/#person\",\"name\":\"CyStack Tutorial\"},{\"@type\":\"WebSite\",\"@id\":\"https://blog.cystack.org/tutorial/#website\",\"url\":\"https://blog.cystack.org/tutorial\",\"name\":\"CyStack Tutorial\",\"publisher\":{\"@id\":\"https://blog.cystack.org/tutorial/#person\"},\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https://s2.cystack.net/tutorial/16144251/builder-design-pattern-trong-java.jpg\",\"url\":\"https://s2.cystack.net/tutorial/16144251/builder-design-pattern-trong-java.jpg\",\"width\":\"1200\",\"height\":\"630\",\"caption\":\"Builder Design Pattern trong Java\",\"inLanguage\":\"en-US\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://blog.cystack.org/tutorial/2025/07/16/builder-design-pattern-trong-java/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":\"1\",\"item\":{\"@id\":\"https://blog.cystack.org/tutorial\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"position\":\"2\",\"item\":{\"@id\":\"https://blog.cystack.org/tutorial/category/java/\",\"name\":\"Java\"}},{\"@type\":\"ListItem\",\"position\":\"3\",\"item\":{\"@id\":\"https://blog.cystack.org/tutorial/2025/07/16/builder-design-pattern-trong-java/\",\"name\":\"Builder Design Pattern trong Java\"}}]},{\"@type\":\"WebPage\",\"@id\":\"https://blog.cystack.org/tutorial/2025/07/16/builder-design-pattern-trong-java/#webpage\",\"url\":\"https://blog.cystack.org/tutorial/2025/07/16/builder-design-pattern-trong-java/\",\"name\":\"Builder Design Pattern trong Java - CyStack Tutorial\",\"datePublished\":\"2025-07-16T14:43:59+07:00\",\"dateModified\":\"2025-07-16T14:44:31+07:00\",\"isPartOf\":{\"@id\":\"https://blog.cystack.org/tutorial/#website\"},\"primaryImageOfPage\":{\"@id\":\"https://s2.cystack.net/tutorial/16144251/builder-design-pattern-trong-java.jpg\"},\"inLanguage\":\"en-US\",\"breadcrumb\":{\"@id\":\"https://blog.cystack.org/tutorial/2025/07/16/builder-design-pattern-trong-java/#breadcrumb\"}},{\"@type\":\"Person\",\"@id\":\"https://blog.cystack.org/tutorial/author/baotran/\",\"name\":\"Bao Tran\",\"url\":\"https://blog.cystack.org/tutorial/author/baotran/\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https://secure.gravatar.com/avatar/0cdd33c02ec4a531fcf557b9c1ccc276df0c69031b2382c959bcf335248e840c?s=96&d=mm&r=g\",\"url\":\"https://secure.gravatar.com/avatar/0cdd33c02ec4a531fcf557b9c1ccc276df0c69031b2382c959bcf335248e840c?s=96&d=mm&r=g\",\"caption\":\"Bao Tran\",\"inLanguage\":\"en-US\"}},{\"@type\":\"BlogPosting\",\"headline\":\"Builder Design Pattern trong Java - CyStack Tutorial\",\"keywords\":\"Builder Design Pattern\",\"datePublished\":\"2025-07-16T14:43:59+07:00\",\"dateModified\":\"2025-07-16T14:44:31+07:00\",\"articleSection\":\"Java\",\"author\":{\"@id\":\"https://blog.cystack.org/tutorial/author/baotran/\",\"name\":\"Bao Tran\"},\"publisher\":{\"@id\":\"https://blog.cystack.org/tutorial/#person\"},\"description\":\"\\u0110\\u1ecdc b\\u00e0i vi\\u1ebft n\\u00e0y \\u0111\\u1ec3 bi\\u1ebft c\\u00e1ch s\\u1eed d\\u1ee5ng Builder design pattern trong Java, h\\u1ed7 tr\\u1ee3 t\\u1ea1o c\\u00e1c \\u0111\\u1ed1i t\\u01b0\\u1ee3ng c\\u00f3 nhi\\u1ec1u thu\\u1ed9c t\\u00ednh t\\u00f9y ch\\u1ecdn m\\u00e0 kh\\u00f4ng c\\u1ea7n ph\\u1ea3i truy\\u1ec1n \\u0111\\u1ea7y \\u0111\\u1ee7 ho\\u1eb7c t\\u1ea1o constructor d\\u00e0i d\\u00f2ng.\",\"name\":\"Builder Design Pattern trong Java - CyStack Tutorial\",\"@id\":\"https://blog.cystack.org/tutorial/2025/07/16/builder-design-pattern-trong-java/#richSnippet\",\"isPartOf\":{\"@id\":\"https://blog.cystack.org/tutorial/2025/07/16/builder-design-pattern-trong-java/#webpage\"},\"image\":{\"@id\":\"https://s2.cystack.net/tutorial/16144251/builder-design-pattern-trong-java.jpg\"},\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https://blog.cystack.org/tutorial/2025/07/16/builder-design-pattern-trong-java/#webpage\"}}]}</script>\n"}