Sự khác biệt giữa mẫu thiết kế Builder và mẫu thiết kế Factory là gì?
Cái nào có lợi hơn và tại sao?
Làm cách nào để trình bày những phát hiện của tôi dưới dạng biểu đồ nếu tôi muốn kiểm tra và so sánh / đối chiếu các mẫu này?
Sự khác biệt giữa mẫu thiết kế Builder và mẫu thiết kế Factory là gì?
Cái nào có lợi hơn và tại sao?
Làm cách nào để trình bày những phát hiện của tôi dưới dạng biểu đồ nếu tôi muốn kiểm tra và so sánh / đối chiếu các mẫu này?
Câu trả lời:
Với các mẫu thiết kế, thường không có giải pháp "thuận lợi hơn" nào phù hợp với mọi trường hợp. Nó phụ thuộc vào những gì bạn cần thực hiện.
Từ Wikipedia:
- Builder tập trung vào việc xây dựng một đối tượng phức tạp từng bước. Tóm tắt Factory nhấn mạnh một họ các đối tượng sản phẩm (đơn giản hoặc phức tạp). Builder trả lại sản phẩm là bước cuối cùng, nhưng theo như Nhà máy Trừu tượng có liên quan, sản phẩm sẽ được trả lại ngay lập tức.
- Builder thường xây dựng một Composite.
- Thông thường, các thiết kế bắt đầu sử dụng Phương thức nhà máy (ít phức tạp hơn, dễ tùy biến hơn, các lớp con tăng sinh) và phát triển theo hướng Tóm tắt Factory, Prototype hoặc Builder (linh hoạt hơn, phức tạp hơn) khi nhà thiết kế phát hiện ra nơi nào cần linh hoạt hơn.
- Đôi khi các mẫu sáng tạo là bổ sung: Builder có thể sử dụng một trong các mẫu khác để triển khai các thành phần nào được xây dựng. Tóm tắt Factory, Builder và Prototype có thể sử dụng Singleton trong việc triển khai.
Mục nhập Wikipedia cho mẫu thiết kế nhà máy: http://en.wikipedia.org/wiki/Factory_method_potype
Mục nhập Wikipedia cho mẫu thiết kế của trình xây dựng: http://en.wikipedia.org/wiki/Builder_potype
Một nhà máy chỉ đơn giản là một hàm bao bọc xung quanh một hàm tạo (có thể là một lớp trong một lớp khác). Sự khác biệt chính là một mẫu phương thức nhà máy yêu cầu toàn bộ đối tượng được xây dựng trong một lệnh gọi phương thức duy nhất, với tất cả các tham số được truyền vào trên một dòng. Đối tượng cuối cùng sẽ được trả lại.
Mặt khác, một mẫu xây dựng về bản chất là một đối tượng trình bao quanh tất cả các tham số có thể bạn có thể muốn chuyển vào một lời gọi của hàm tạo. Điều này cho phép bạn sử dụng các phương thức setter để từ từ xây dựng danh sách tham số của mình. Một phương thức bổ sung trên lớp trình xây dựng là phương thức build (), chỉ đơn giản chuyển đối tượng trình xây dựng vào hàm tạo mong muốn và trả về kết quả.
Trong các ngôn ngữ tĩnh như Java, điều này trở nên quan trọng hơn khi bạn có nhiều hơn một số tham số (có khả năng tùy chọn), vì nó tránh được yêu cầu phải có các hàm tạo kính thiên văn cho tất cả các kết hợp tham số có thể. Ngoài ra, một trình xây dựng cho phép bạn sử dụng các phương thức setter để xác định các trường chỉ đọc hoặc riêng không thể sửa đổi trực tiếp sau khi hàm tạo được gọi.
Ví dụ nhà máy cơ bản
// Factory
static class FruitFactory {
static Fruit create(name, color, firmness) {
// Additional logic
return new Fruit(name, color, firmness);
}
}
// Usage
Fruit fruit = FruitFactory.create("apple", "red", "crunchy");
Ví dụ về Trình tạo cơ bản
// Builder
class FruitBuilder {
String name, color, firmness;
FruitBuilder setName(name) { this.name = name; return this; }
FruitBuilder setColor(color) { this.color = color; return this; }
FruitBuilder setFirmness(firmness) { this.firmness = firmness; return this; }
Fruit build() {
return new Fruit(this); // Pass in the builder
}
}
// Usage
Fruit fruit = new FruitBuilder()
.setName("apple")
.setColor("red")
.setFirmness("crunchy")
.build();
Có thể đáng để so sánh các mẫu mã từ hai trang wikipedia này:
http://en.wikipedia.org/wiki/Factory_method_potype
http://en.wikipedia.org/wiki/Builder_potype
Mẫu Factory gần như có thể được xem là một phiên bản đơn giản của mẫu Builder.
Trong mẫu Factory , nhà máy chịu trách nhiệm tạo ra các kiểu con khác nhau của một đối tượng tùy thuộc vào nhu cầu.
Người sử dụng một phương thức xuất xưởng không cần biết chính xác kiểu con của đối tượng đó. Một ví dụ về phương thức xuất xưởng createCar
có thể trả về một Ford
hoặc một Honda
đối tượng đã gõ.
Trong mẫu Builder , các kiểu con khác nhau cũng được tạo bởi một phương thức xây dựng, nhưng thành phần của các đối tượng có thể khác nhau trong cùng một lớp con.
Để tiếp tục ví dụ về xe hơi, bạn có thể có một createCar
phương pháp xây dựng để tạo ra một Honda
đối tượng được phân loại bằng động cơ 4 xi lanh hoặc một Honda
đối tượng được phân loại với 6 xi lanh. Mẫu xây dựng cho phép độ chi tiết mịn hơn này.
Các sơ đồ của cả mẫu Builder và mẫu phương thức Factory đều có sẵn trên Wikipedia.
Mẫu thiết kế trình xây dựng mô tả một đối tượng biết cách tạo một đối tượng khác thuộc một loại cụ thể qua nhiều bước. Nó giữ trạng thái cần thiết cho mục tiêu ở mỗi bước trung gian. Hãy nghĩ những gì StringBuilder trải qua để tạo ra một chuỗi cuối cùng.
Mẫu thiết kế nhà máy mô tả một đối tượng biết cách tạo ra một số loại đối tượng khác nhau nhưng có liên quan trong một bước, trong đó loại cụ thể được chọn dựa trên các tham số đã cho. Hãy nghĩ về hệ thống tuần tự hóa, nơi bạn tạo serializer của mình và nó xây dựng mong muốn trong đối tượng tất cả trong một cuộc gọi tải.
Xây dựng một đối tượng phức tạp từng bước: mô hình trình xây dựng
Một đối tượng đơn giản được tạo bằng cách sử dụng một phương thức duy nhất: mẫu phương thức nhà máy
Tạo đối tượng bằng cách sử dụng nhiều phương thức nhà máy: Mẫu nhà máy trừu tượng
Mẫu Builder và mẫu Factory, cả hai đều có vẻ khá giống với mắt thường vì cả hai đều tạo đối tượng cho bạn.
Ví dụ thực tế này sẽ làm cho sự khác biệt giữa hai rõ ràng hơn.
Giả sử, bạn đã đến một nhà hàng thức ăn nhanh và bạn gọi món .
pizza
Capsicum, cà chua, gà BBQ, KHÔNG PINEAPPLE
Vì vậy, các loại thực phẩm khác nhau được tạo ra bởi mẫu Factory nhưng các biến thể (hương vị) khác nhau của một loại thực phẩm cụ thể được tạo ra bởi mẫu Builder.
Các loại thực phẩm khác nhau
Pizza, Burger, Pasta
Biến thể của Pizza
Chỉ có phô mai, phô mai + cà chua + ớt tây, phô mai + cà chua v.v.
Bạn có thể thấy việc triển khai mã mẫu của cả hai mẫu ở đây
Builder Pattern
Factory Pattern
Cả hai đều là mẫu Tạo, để tạo Đối tượng.
1) Mô hình nhà máy - Giả sử, bạn có một siêu lớp và N số lớp phụ. Đối tượng được tạo phụ thuộc vào tham số / giá trị nào được thông qua.
2) Mẫu xây dựng - để tạo đối tượng phức tạp.
Ex: Make a Loan Object. Loan could be house loan, car loan ,
education loan ..etc. Each loan will have different interest rate, amount ,
duration ...etc. Finally a complex object created through step by step process.
Đầu tiên một số điều chung để làm theo lập luận của tôi:
Thách thức chính trong việc thiết kế các hệ thống phần mềm lớn là chúng phải linh hoạt và không phức tạp để thay đổi. Vì lý do này, có một số số liệu như khớp nối và sự gắn kết. Để đạt được các hệ thống có thể dễ dàng thay đổi hoặc mở rộng chức năng của nó mà không cần thiết kế lại toàn bộ hệ thống từ đầu, bạn có thể tuân theo các nguyên tắc thiết kế (như RẮN, v.v.). Sau một thời gian, một số nhà phát triển nhận ra rằng nếu họ tuân theo những nguyên tắc đó, có một số giải pháp tương tự hoạt động tốt với các vấn đề tương tự. Những giải pháp tiêu chuẩn hóa ra là các mẫu thiết kế.
Vì vậy, các mẫu thiết kế là để hỗ trợ bạn tuân theo các nguyên tắc thiết kế chung để đạt được các hệ thống liên kết lỏng lẻo với độ gắn kết cao.
Trả lời câu hỏi:
Bằng cách hỏi sự khác biệt giữa hai mẫu, bạn phải tự hỏi mẫu nào làm cho hệ thống của bạn linh hoạt hơn. Mỗi mẫu có mục đích riêng để tổ chức các phụ thuộc giữa các lớp trong hệ thống của bạn.
Mô hình nhà máy trừu tượng: GoF : xông Cung cấp giao diện để tạo các họ của các đối tượng liên quan hoặc phụ thuộc mà không chỉ định các lớp cụ thể của họ.
Điều này có nghĩa là gì: Bằng cách cung cấp một giao diện như thế này, cuộc gọi đến nhà xây dựng của mỗi sản phẩm của gia đình được gói gọn trong lớp nhà máy. Và bởi vì đây là nơi duy nhất trong toàn bộ hệ thống của bạn nơi những người xây dựng đó được gọi nên bạn có thể thay đổi hệ thống của mình bằng cách triển khai một lớp nhà máy mới. Nếu bạn trao đổi đại diện của nhà máy thông qua nhà máy khác, bạn có thể trao đổi toàn bộ bộ sản phẩm mà không cần chạm vào phần lớn mã của bạn.
Mẫu xây dựng: GoF : Triệu Tách việc xây dựng một đối tượng phức tạp khỏi biểu diễn của nó để cùng một quy trình xây dựng có thể tạo ra các biểu diễn khác nhau.
Điều này có nghĩa là gì: Bạn gói gọn quá trình xây dựng trong một lớp khác, được gọi là giám đốc (GoF). Giám đốc này chứa thuật toán tạo các phiên bản mới của sản phẩm (ví dụ: tạo một sản phẩm phức tạp ra khỏi các phần khác). Để tạo ra các phần không thể thiếu của toàn bộ sản phẩm, giám đốc sử dụng một người xây dựng. Bằng cách trao đổi trình xây dựng trong giám đốc, bạn có thể sử dụng cùng một thuật toán để tạo ra sản phẩm, nhưng thay đổi cách biểu diễn của các bộ phận đơn lẻ (và do đó, đại diện của sản phẩm). Để mở rộng hoặc sửa đổi hệ thống của bạn trong việc thể hiện sản phẩm, tất cả những gì bạn cần làm là triển khai một lớp trình tạo mới.
Vì vậy, tóm lại: Mục đích của Mô hình Nhà máy Trừu tượng là trao đổi một bộ sản phẩm được sản xuất để sử dụng cùng nhau. Mục đích của Mẫu xây dựng là gói gọn thuật toán trừu tượng tạo ra sản phẩm để tái sử dụng nó cho các cách biểu diễn khác nhau của sản phẩm.
Theo tôi, bạn không thể nói rằng Mẫu nhà máy trừu tượng là người anh lớn của Mẫu xây dựng. CÓ, cả hai đều là các mẫu sáng tạo, nhưng mục đích chính của các mẫu là hoàn toàn khác nhau.
Một điểm khác biệt nổi bật giữa Builder & nhà máy mà tôi có thể nhận ra là như sau
giả sử chúng ta có một chiếc xe hơi
class Car
{
bool HasGPS;
bool IsCityCar;
bool IsSportsCar;
int Cylenders;
int Seats;
public:
void Car(bool hasGPs=false,bool IsCityCar=false,bool IsSportsCar=false, int Cylender=2, int Seats=4);
};
Trong giao diện trên, chúng ta có thể lấy xe bằng cách sau:
int main()
{
BadCar = new Car(false,false,true,4,4);
}
Nhưng nếu, một số ngoại lệ xảy ra trong khi tạo Ghế ngồi ??? BẠN S GET KHÔNG NHẬN ĐỐI TƯỢNG TẠI TẤT CẢ // NHƯNG
giả sử bạn có cách thực hiện như sau
class Car
{
bool mHasGPS;
bool mIsCityCar;
bool mIsSportsCar;
int mCylenders;
int mSeats;
public:
void Car() : mHasGPs(false), mIsCityCar(false), mIsSportsCar(false), mCylender(2), mSeats(4) {}
void SetGPS(bool hasGPs=false) {mHasGPs = hasGPs;}
void SetCity(bool CityCar) {mIsCityCar = CityCar;}
void SetSports(bool SportsCar) {mIsSportsCar = SportsCar;}
void SetCylender(int Cylender) {mCylenders = Cylender;}
void SetSeats(int seat) {mSeats = seat;}
};
class CarBuilder
{
Car* mCar;
public:
CarBuilder():mCar(NULL) { mCar* = new Car(); }
~CarBuilder() { if(mCar) { delete mCar; }
Car* GetCar() { return mCar; mCar=new Car(); }
CarBuilder* SetSeats(int n) { mCar->SetSeats(n); return this; }
CarBuilder* SetCylender(int n) { mCar->SetCylender(n); return this; }
CarBuilder* SetSports(bool val) { mCar->SetSports(val); return this; }
CarBuilder* SetCity(bool val) { mCar->SetCity(val); return this; }
CarBuilder* SetGPS(bool val) { mCar->SetGPS(val); return this; }
}
Bây giờ bạn có thể tạo như thế này
int main()
{
CarBuilder* bp =new CarBuilder;
Car* NewCar = bp->SetSeats(4)->SetSports(4)->SetCity(ture)->SetGPS(false)->SetSports(true)->GetCar();
bp->SetSeats(2);
bp->SetSports(4);
bp->SetCity(ture);
bp->SetSports(true)
Car* Car_II= bp->GetCar();
}
Ở đây trong trường hợp thứ hai, ngay cả khi một thao tác thất bại, bạn vẫn sẽ nhận được Xe.
Có thể chiếc xe đó không hoạt động hoàn hảo sau đó, nhưng bạn sẽ có đối tượng.
Bởi vì Phương thức nhà máy cung cấp cho bạn Xe trong một cuộc gọi, trong khi Builder xây dựng từng cái một.
Mặc dù, nó phụ thuộc vào nhu cầu của vị trí mà người ta sẽ đi.
+-------------------------------------------------------------------+---------------------------------------------------+
| Builder | Factory |
+-------------------------------------------------------------------+---------------------------------------------------+
| Return only single instance to handle complex object construction | Retrun various instances on multiple constructors |
| No interface required | Interface driven |
| Inner classes is involved (to avoid telescopic constructors) | Subclasses are involved |
+-------------------------------------------------------------------+---------------------------------------------------+
Sự giống nhau:
Builder và Tóm tắt Factory có ý nghĩa cho các mục đích khác nhau. Tùy thuộc vào trường hợp sử dụng đúng, bạn phải chọn mẫu thiết kế phù hợp.
Tính năng nổi bật của Builder :
Nhà máy ( Nhà máy đơn giản) tính năng nổi bật:
Thông thường, các thiết kế bắt đầu sử dụng Phương thức nhà máy (ít phức tạp hơn, tùy biến hơn, các lớp con tăng sinh) và phát triển theo hướng Tóm tắt Factory , Prototype hoặc Builder (linh hoạt hơn, phức tạp hơn)
Có một cái nhìn vào bài viết liên quan:
Giữ trình xây dựng trong lớp riêng biệt (giao diện lưu loát)
Mẫu thiết kế: Phương pháp Factory vs Factory vs Tóm tắt Factory
Bạn có thể tham khảo các bài viết dưới đây để biết thêm chi tiết:
Factory : Được sử dụng để tạo một thể hiện của một đối tượng trong đó các phụ thuộc của đối tượng hoàn toàn do nhà máy nắm giữ. Đối với mô hình nhà máy trừu tượng , thường có nhiều triển khai cụ thể của cùng một nhà máy trừu tượng. Việc thực hiện đúng của nhà máy được tiêm thông qua tiêm phụ thuộc.
Trình tạo : Được sử dụng để xây dựng các đối tượng bất biến , khi các phụ thuộc của đối tượng được khởi tạo được biết trước một phần và được cung cấp một phần bởi khách hàng của trình tạo.
Tóm tắt mẫu Factory & Builder là cả hai mẫu Creational nhưng với mục đích khác nhau.
Tóm tắt Factory Pattern nhấn mạnh việc tạo đối tượng cho gia đình của các đối tượng liên quan trong đó:
Mô hình xây dựng tập trung vào việc xây dựng một đối tượng phức tạp từng bước. Nó tách rời biểu diễn khỏi quá trình xây dựng đối tượng phức tạp, để có thể sử dụng cùng một quy trình xây dựng cho các biểu diễn khác nhau.
Một cấu trúc phức tạp là khi đối tượng được xây dựng bao gồm các đối tượng khác được thể hiện bằng sự trừu tượng.
Hãy xem xét một thực đơn ở McDonald. Một menu chứa một thức uống, một chính và một bên. Tùy thuộc vào hậu duệ của các tóm tắt riêng lẻ được kết hợp với nhau, menu được tạo có một đại diện khác.
Ở đó, chúng tôi có hai phiên bản của menu với các cách trình bày khác nhau. Quá trình xây dựng lần lượt vẫn như cũ. Bạn tạo một menu với một thức uống, một chính và một bên.
Bằng cách sử dụng mẫu xây dựng, bạn tách thuật toán tạo một đối tượng phức tạp khỏi các thành phần khác nhau được sử dụng để tạo ra nó.
Về mặt mẫu xây dựng, thuật toán được gói gọn trong giám đốc trong khi các trình xây dựng được sử dụng để tạo các phần tách rời. Thay đổi trình xây dựng được sử dụng trong thuật toán của giám đốc dẫn đến một biểu diễn khác vì các phần khác được tạo thành một menu. Cách một menu được tạo ra vẫn giữ nguyên.
Sự khác biệt chính giữa chúng là mẫu Builder chủ yếu mô tả việc tạo các đối tượng phức tạp từng bước. Trong mô hình Nhà máy Trừu tượng, trọng tâm là các họ sản phẩm của đối tượng . Builder trả lại sản phẩm ở bước cuối cùng . Trong khi trong mẫu Tóm tắt Nhà máy, sản phẩm có sẵn ngay lập tức .
Ví dụ: Giả sử chúng ta đang tạo Mê cung
1. Nhà máy trừu tượng:
Maze* MazeGame::CreateMaze (MazeFactory& factory) {
Maze* maze = factory.MakeMaze(); /// product is available at start!!
/* Call some methods on maze */
return maze;
}
2. Người xây dựng:
Maze* MazeGame::CreateMaze (MazeBuilder& builder) {
builder.buildMaze(); /// We don't have access to maze
/* Call some methods on builder */
return builder.GetMaze();
}
Tôi tin rằng, việc sử dụng và sự khác biệt giữa các mẫu Factory & Builder có thể được hiểu / làm rõ dễ dàng hơn trong một khoảng thời gian nhất định khi bạn làm việc trên cùng một cơ sở mã và thay đổi các yêu cầu.
Theo kinh nghiệm của tôi, thông thường, bạn bắt đầu với một mẫu Factory bao gồm một vài phương thức của trình tạo tĩnh để chủ yếu che giấu logic khởi tạo tương đối phức tạp. Khi hệ thống phân cấp đối tượng của bạn trở nên phức tạp hơn (hoặc khi bạn thêm nhiều loại, tham số), có thể cuối cùng bạn sẽ có các phương thức của mình với nhiều tham số hơn và không đề cập đến việc bạn sẽ phải biên dịch lại mô-đun Factory. Tất cả những thứ đó, làm tăng sự phức tạp của các phương thức người tạo của bạn, làm giảm khả năng đọc và làm cho mô-đun tạo dễ vỡ hơn.
Điểm này có thể sẽ là điểm chuyển tiếp / mở rộng. Bằng cách làm như vậy, bạn tạo một mô-đun trình bao quanh các tham số xây dựng và sau đó bạn sẽ có thể biểu diễn các đối tượng mới (tương tự) bằng cách thêm một số trừu tượng (có lẽ) và triển khai mà không cần chạm vào logic tạo thực tế của bạn. Vì vậy, bạn đã có "ít" logic phức tạp.
Thành thật mà nói, đề cập đến một cái gì đó "có một đối tượng được tạo ra trong một bước hoặc nhiều bước là sự khác biệt" vì yếu tố đa dạng duy nhất là không đủ để tôi phân biệt chúng vì tôi có thể sử dụng cả hai cách cho hầu hết các trường hợp mà tôi phải đối mặt bây giờ mà không trải nghiệm bất kỳ lợi ích. Vì vậy, đây là những gì tôi cuối cùng đã nghĩ về nó.
Ưu điểm chính của mẫu xây dựng so với mẫu của nhà máy là trong trường hợp nếu bạn muốn tạo một số đối tượng tiêu chuẩn với nhiều tùy chỉnh có thể, nhưng bạn thường chỉ tùy chỉnh một vài thứ.
Ví dụ: nếu bạn muốn viết Máy khách HTTP - bạn sẽ thiết lập một số tham số mặc định như thời gian chờ ghi / đọc mặc định, giao thức, bộ đệm, DNS, chặn, v.v.
Hầu hết người dùng của khách hàng của bạn sẽ chỉ sử dụng các tham số mặc định đó, trong khi một số người dùng khác có thể muốn tùy chỉnh một số tham số khác. Trong một số trường hợp, bạn sẽ chỉ muốn thay đổi thời gian chờ và sử dụng phần còn lại, trong khi trong các trường hợp khác, bạn có thể cần tùy chỉnh ví dụ như bộ đệm.
Dưới đây là những cách có thể để khởi tạo ứng dụng khách của bạn (lấy từ OkHttpClient):
//just give me the default stuff
HttpClient.Builder().build()
//I want to use custom cache
HttpClient.Builder().cache(MyCache()).build()
//I want custom connection timeout
HttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS).build()
//I am more interested in read/write timeout
HttpClient.Builder()
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS).build()
Nếu bạn sử dụng mẫu nhà máy cho việc này, cuối cùng bạn sẽ viết rất nhiều phương thức với tất cả các kết hợp tham số có thể có. Với trình xây dựng, bạn chỉ cần chỉ định những người bạn quan tâm và để trình xây dựng xây dựng nó cho bạn chăm sóc tất cả các thông số khác.
Mô hình xây dựng nhấn mạnh vào sự phức tạp của việc tạo đối tượng (được giải quyết bằng "các bước")
Mẫu trừu tượng nhấn mạnh "chỉ" vào "trừu tượng" của các đối tượng (nhiều nhưng có liên quan).
Sự khác biệt là rõ ràng Trong mẫu trình tạo, trình xây dựng sẽ tạo loại đối tượng cụ thể cho bạn. Bạn phải nói những gì người xây dựng phải xây dựng. Trong mô hình nhà máy, sử dụng lớp trừu tượng, bạn đang trực tiếp xây dựng đối tượng cụ thể.
Ở đây lớp xây dựng đóng vai trò trung gian giữa lớp chính và các lớp loại cụ thể. Trừu tượng hơn.
Cả hai đều rất giống nhau, nhưng nếu bạn có một số lượng lớn các tham số để tạo đối tượng với một số tùy chọn với một số giá trị mặc định, hãy chọn mẫu Builder.
IMHO
Builder là một số loại Nhà máy phức tạp hơn.
Nhưng trong Builder bạn có thể khởi tạo các đối tượng bằng cách sử dụng các nhà máy khác , được yêu cầu để xây dựng đối tượng cuối cùng và hợp lệ.
Vì vậy, nói về sự tiến hóa của "Mô hình sáng tạo" bởi sự phức tạp, bạn có thể nghĩ về nó theo cách này:
Dependency Injection Container -> Service Locator -> Builder -> Factory
Cả hai mẫu đều có cùng một nhu cầu: Ẩn khỏi một số mã khách hàng logic xây dựng của một đối tượng phức tạp. Nhưng điều gì làm cho "phức tạp" (hoặc, đôi khi, làm phức tạp) một đối tượng? Chủ yếu, đó là do sự phụ thuộc, hay đúng hơn là trạng thái của một đối tượng được cấu thành bởi các trạng thái một phần hơn. Bạn có thể thêm các phụ thuộc của hàm tạo để đặt trạng thái đối tượng ban đầu, nhưng một đối tượng có thể yêu cầu rất nhiều trong số chúng, một số sẽ ở trạng thái ban đầu mặc định (chỉ vì chúng ta đã biết rằng đặt phụ thuộc mặc định thành null không phải là cách sạch nhất ) và một số khác được đặt thành trạng thái được điều khiển bởi một số điều kiện. Hơn nữa, có các thuộc tính đối tượng là một số loại "phụ thuộc không biết" nhưng chúng cũng có thể giả sử các trạng thái tùy chọn.
Có hai cách nổi tiếng để chi phối sự phức tạp đó:
Thành phần / tập hợp: Xây dựng một đối tượng, xây dựng các đối tượng phụ thuộc của nó, sau đó nối với nhau. Ở đây, một người xây dựng có thể thực hiện quy trình minh bạch và linh hoạt để xác định các quy tắc dẫn đến việc xây dựng thành phần.
Đa hình: Các quy tắc xây dựng được khai báo trực tiếp thành định nghĩa tiểu loại, do đó bạn có một bộ quy tắc cho mỗi loại phụ và một số điều kiện quyết định một trong số các quy tắc này áp dụng để xây dựng đối tượng. Một nhà máy phù hợp hoàn hảo trong kịch bản này.
Không có gì ngăn cản để trộn lẫn hai cách tiếp cận này. Một họ sản phẩm có thể tạo đối tượng trừu tượng được thực hiện với một người xây dựng, một người xây dựng có thể sử dụng các nhà máy để xác định đối tượng thành phần nào khởi tạo.
Theo tôi, mẫu Builder được sử dụng khi bạn muốn tạo một đối tượng từ một loạt các đối tượng khác và việc tạo một phần cần phải độc lập với đối tượng bạn muốn tạo. Nó giúp ẩn việc tạo một phần từ máy khách để làm cho trình xây dựng và máy khách trở nên độc lập. Nó được sử dụng để tạo các đối tượng phức tạp (các đối tượng có thể bao gồm các thuộc tính phức tạp)
Trong khi mẫu nhà máy chỉ định rằng bạn muốn tạo các đối tượng của một gia đình chung và bạn muốn nó được xử lý cùng một lúc. Nó được sử dụng cho các đối tượng đơn giản hơn.
Nhà máy xây dựng và trừu tượng
Ở một mức độ nào đó, mẫu thiết kế Builder rất giống với mẫu Tóm tắt của Nhà máy. Đó là lý do tại sao điều quan trọng là có thể tạo ra sự khác biệt giữa các tình huống khi sử dụng cái này hoặc cái kia. Trong trường hợp của Nhà máy Trừu tượng, khách hàng sử dụng các phương thức của nhà máy để tạo các đối tượng của riêng mình. Trong trường hợp của Trình xây dựng, lớp Builder được hướng dẫn cách tạo đối tượng và sau đó nó được yêu cầu, nhưng cách mà lớp được kết hợp với nhau tùy thuộc vào lớp Builder, chi tiết này tạo ra sự khác biệt giữa hai mẫu.
Giao diện chung cho sản phẩm
Trong thực tế, các sản phẩm được tạo bởi các nhà xây dựng bê tông có cấu trúc khác nhau đáng kể, vì vậy nếu không có lý do để lấy các sản phẩm khác nhau thì một lớp cha mẹ chung. Điều này cũng phân biệt mẫu Builder với mẫu Tóm tắt Factory tạo ra các đối tượng xuất phát từ một loại phổ biến.
Mô hình nhà máy tạo ra một triển khai cụ thể của một lớp trong thời gian chạy, tức là mục đích chính của nó là sử dụng đa hình để cho phép các lớp con quyết định lớp nào sẽ khởi tạo. Điều này có nghĩa là tại thời điểm biên dịch, chúng ta không biết chính xác lớp sẽ được tạo, trong khi mẫu Builder chủ yếu liên quan đến việc giải quyết vấn đề của các kiến trúc sư kính viễn vọng, phát sinh do một số lượng lớn các trường tùy chọn của một lớp. Trong mẫu xây dựng không có khái niệm về đa hình, vì chúng ta biết đối tượng nào chúng ta đang cố gắng xây dựng tại thời điểm biên dịch.
Chủ đề chung duy nhất của hai mẫu này là ẩn các hàm tạo và tạo đối tượng đằng sau các phương thức nhà máy và phương thức xây dựng, để cải thiện việc xây dựng đối tượng.
Mẫu nhà máy cho phép bạn tạo một đối tượng cùng một lúc trong khi mẫu xây dựng cho phép bạn phá vỡ quy trình tạo của đối tượng. Theo cách này, bạn có thể thêm các chức năng khác nhau trong quá trình tạo đối tượng.