Sự khác biệt giữa mẫu Builder Design và mẫu Design Design là gì?


662

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?


12
Vì họ làm những việc khác nhau, bạn có ý nghĩa gì bởi "lợi thế"?
S.Lott

5
Builder là một phiên bản phức tạp hơn của hàm tạo - trong khi phương thức nhà máy là một phương thức đơn giản hóa.
Dávid Horváth

@ DávidHorváth Tôi sẽ không mô tả một Builder là "phức tạp hơn". Khi bạn giao dịch với một hàm tạo có 100 tham số và bạn chỉ quan tâm đến 3 tham số đó và bạn biết số lượng tham số có thể thay đổi trong tương lai, sử dụng mẫu Builder sẽ giúp cuộc sống của mọi người đơn giản hơn rất nhiều.
Aberrant

@Aberrant Sử dụng phức tạp và phức tạp kiến ​​trúc là hai điều khác nhau. Tôi tập trung vào cái sau.
Dávid Horváth

Câu trả lời:


466

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


159
Đây chính xác là sự khác biệt. Builder chỉ cần thiết khi một đối tượng không thể được tạo ra trong một bước. Một ví dụ tuyệt vời về điều này sẽ là trong quá trình khử tuần tự hóa cho một đối tượng phức tạp. Thông thường, các tham số cho đối tượng phức tạp phải được truy xuất từng cái một.
Bernard Igiri

1
Đối với câu đầu tiên, tôi sẽ nói rằng thường có một giải pháp có lợi hơn, áp dụng rộng rãi ... chúng ta không thấy những điều này, vì cuối cùng chúng được đưa thẳng vào ngôn ngữ lập trình.
Joel Coehoorn

4
@Joel: Tôi đồng ý rằng một số mẫu phổ biến hơn các mẫu khác (ví dụ: Factory dường như phổ biến hơn Builder), nhưng ý tôi là không có mẫu nào luôn tốt hơn mẫu kia, cho dù kịch bản trông như thế nào .
Adrian Grigore

@AdrianGrigore sẽ thế nào nếu trộn cả hai thứ đó? Aso.net mvc có Trình điều khiển đã thiết lập và nhận phương thức cho lớp ControllerFactory
AminM

Goood trả lời, mặc dù 2 điều đáng để thêm vào là: 1) Builder chủ yếu được sử dụng để xây dựng POJO bằng Fluent API (ví dụ Person.builder (). WithName ("Sam"). WithAge (38) .build (). 2) Trong experiene của tôi, trình xây dựng rất hữu ích cho việc tạo POJO cho các đối tượng miền, trong khi đó nhà máy rất hữu ích để tạo một đối tượng dịch vụ như lớp PdfGeneratorFactory. Đối tượng dịch vụ có thể được lưu trong bộ nhớ cache của nhà máy trong hơn 1 lần sử dụng, trong khi đó, trình xây dựng luôn tạo một đối tượng mới theo thiết kế.
saurabh.in

357

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


1
Đó không phải là cách sử dụng chính xác của mẫu xây dựng imo, ngay cả trong liên kết wiki bạn sử dụng cũng khác. FruitBuilder này là một số kết hợp của thành phần Director và Builder nơi bạn gọi build () thuộc về Director và setters thuộc về thành phần Builder. Giám đốc nên chứa logic nghiệp vụ về cách tạo đối tượng bằng các phương thức Builders. Apis thông thạo không phải là mẫu xây dựng và StringBuilder cũng không phải là mẫu xây dựng.
Kmaczek

281

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 createCarcó thể trả về một Fordhoặ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 createCarphươ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 Buildermẫu phương thức Factory đều có sẵn trên Wikipedia.


13
Mẫu xây dựng giống như phóng to để xây dựng các đối tượng lớn. Đối tượng lớn bao gồm các đối tượng khác được sáng tác thêm như đệ quy. Trong khi nhà máy sẽ chỉ giúp bạn có được điều đó trong một cuộc gọi. Sự hiểu biết này có đúng không?
Fooo

63

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.


7
Chỉ cần một số gợi ý: ví dụ điển hình cho mẫu trình xây dựng là "giao diện lưu loát" và ADO.NET có đầy đủ các triển khai "nhà máy" và "nhà máy trừu tượng" (ví dụ: DbFactory).
boj

50
  • 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


21

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.

Nhưng bạn cần nhìn gần hơ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 .

1) Thức ăn gì?

pizza

2) Những gì toppings?

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.

Mẫu mã

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


1
Cảm ơn đã cung cấp mã mẫu! Ví dụ của bạn phân biệt 2 mẫu này rất tốt.
Rommel Paras

18

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.

12

Đầ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.


Câu trả lời hay, giải thích công phu.
kéo xe vào

bạn có thể giải thích ý nghĩa của việc "tách biệt việc xây dựng một vật thể phức tạp khỏi sự đại diện của nó"
Rajdeep

@Rajdeep giải thích là mong muốn nhận xét, đó là lý do tại sao tôi viết một câu trả lời khác.
Janis

@Janis Câu trả lời hoặc nguồn đó từ đâu tôi có thể đọc?
Rajdeep

@Rajdeep tôi khuyên bạn nên đọc cuốn sách Patterns Mẫu thiết kế - amazon.de/Potypes-Elements-ReUs-Object-Orients-Software/iêu
Janis

7

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.


2
Chắc chắn sẽ tốt hơn nếu không có chiếc xe nào hơn một chiếc xe không hợp lệ - điều gì sẽ xảy ra nếu bạn chỉ gặp vấn đề khi bạn sử dụng giờ nghỉ?
Ken

@Ken: Tôi không khẳng định rằng đó là một thiết kế tốt từ triển vọng của dự án thương mại, v.v., ý định trích dẫn ví dụ này để minh họa cho sự khác biệt giữa các mẫu. Chắc chắn, bạn đã đúng rằng điều này là xấu từ kinh nghiệm của người dùng khi nhận được xe xấu, nhưng, hãy xem xét, có một nhà máy sản xuất xe hơi và một số bộ phận bị trục trặc sau đó chiếc xe được sản xuất nhưng bị hỏng hóc thời gian thử nghiệm & vận chuyển chiếc xe đó cho khách hàng đã dừng lại.
Fooo

2
Tôi muốn làm rõ rằng tôi thực sự là một fan hâm mộ lớn của mẫu xây dựng, tuy nhiên, không phải vì lý do bạn đã đưa ra. Một đối tượng không hợp lệ sẽ thất bại khi xây dựng, càng tìm ra lỗi thì càng đắt. Với mẫu trình xây dựng, sẽ là bình thường đối với phương thức xây dựng (trong ví dụ của bạn được gọi là getCar ()) để đưa ra một ngoại lệ nếu thiếu dữ liệu cần thiết.
Ken

7
+-------------------------------------------------------------------+---------------------------------------------------+
|                              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                           |
+-------------------------------------------------------------------+---------------------------------------------------+  

Mẫu kính viễn vọng

Sự giống nhau:

  • Nhà máy: Hãy xem xét một nhà hàng. Việc tạo ra "bữa ăn hôm nay" là một mô hình nhà máy, bởi vì bạn nói với nhà bếp "hãy cho tôi bữa ăn hôm nay" và nhà bếp (nhà máy) quyết định đối tượng nào sẽ tạo ra, dựa trên các tiêu chí ẩn.
  • Builder: Trình xây dựng xuất hiện nếu bạn đặt một chiếc bánh pizza tùy chỉnh. Trong trường hợp này, người phục vụ nói với đầu bếp (người xây dựng) "Tôi cần một chiếc bánh pizza, thêm phô mai, hành tây và thịt xông khói vào nó!" Do đó, trình xây dựng hiển thị các thuộc tính mà đối tượng được tạo nên có, nhưng ẩn cách đặt chúng.

Phép lịch sự


5

BuilderTó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 :

  1. Mẫu xây dựng xây dựng một đối tượng phức tạp bằng cách sử dụng các đối tượng đơn giản và sử dụng phương pháp tiếp cận từng bước
  2. Một lớp Builder xây dựng đối tượng cuối cùng từng bước. Trình xây dựng này độc lập với các đối tượng khác
  3. Thay thế cho phương thức Factory / Tóm tắt Factory trong kịch bản này: Quá nhiều đối số chuyển từ chương trình máy khách sang lớp Factory có thể dễ bị lỗi
  4. Một số tham số có thể là tùy chọn không giống như trong Factory buộc phải gửi tất cả các tham số

Nhà máy ( Nhà máy đơn giản) tính năng nổi bật:

  1. Mô hình sáng tạo
  2. Dựa trên sự kế thừa
  3. Factory trả về Phương thức nhà máy (giao diện) lần lượt trả về đối tượng Concrete
  4. Bạn có thể thay thế Đối tượng cụ thể mới cho giao diện và ứng dụng khách (người gọi) không nên biết về tất cả các triển khai cụ thể
  5. Máy khách luôn chỉ truy cập giao diện và bạn có thể ẩn chi tiết tạo đối tượng trong phương thức Factory.

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:

làm chua

tạp chí


5

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.


4

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ỗi gia đình là một tập hợp các lớp xuất phát từ một lớp cơ sở / Giao diện chung.
  • Mỗi đối tượng được trả về ngay lập tức do kết quả của một cuộc gọi.

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.

  • Đối tượng Builder đóng gói cấu hình của đối tượng phức tạp.
  • Đối tượng Director biết giao thức sử dụng Builder, trong đó giao thức xác định tất cả các bước logic cần thiết để xây dựng đối tượng phức tạp.

bạn có thể giải thích ý nghĩa của "tách rời sự biểu diễn từ quá trình xây dựng đối tượng phức tạp"
Rajdeep

3

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.

  1. Ví dụ: Cola, Big Mac, khoai tây chiên kiểu Pháp
  2. Ví dụ: Sprite, cốm, khoai tây chiên

Ở đó, 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.


1
Điều này giải thích "sự tách biệt xây dựng của vật thể phức tạp khỏi đại diện của nó"
Rajdeep

2

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();
}

2

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ó.


2

Ư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.


1

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).


1

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.


1

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.


1

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

1

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.


0

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.


0

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.

Từ: http://www.oodesign.com/builder-potype.html


-2

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.


-2

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.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.