2009-12-22 26 views
22

Tôi đã nhìn thấy câu hỏi này tăng lên ở đây và có một vài lần, nhưng tôi không bao giờ tìm thấy và trả lời tôi hài lòng với.Bạn sẽ sử dụng Mô hình Builder ở đâu thay vì Nhà máy Trừu tượng?

Từ Wikipedia:

Builder tập trung vào việc xây dựng một bước đối tượng phức tạp bằng cách bước. Abstract 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ả về sản phẩm dưới dạng 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ả về ngay lập tức.

Nhưng với khách hàng, điều đó cũng không giống nhau? Anh ta nhận được vật thể đầy đủ khi nó được xây dựng, do đó anh ta không có thêm chức năng nào.

Cách duy nhất tôi thấy nó là một cách hoặc tổ chức mã nhà xây dựng theo các bước, để buộc một cấu trúc cho việc triển khai các nhà xây dựng. Đó là tốt đẹp, nhưng hầu như không một bước tiến tuyệt vời từ các nhà máy trừu tượng.


này chút kế tiếp từ Wikipedia là một tài liệu tham khảo tốt để có được quan điểm của tôi:

Thông thường, kiểu dáng bắt đầu bằng cách sử dụng Nhà máy Phương pháp (ít phức tạp hơn, tùy biến nhiều hơn, lớp con sinh sôi nảy nở) và phát triển theo hướng trừu tượng Nhà máy, 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 cần có sự linh hoạt hơn.

Nếu vậy, loại phức tạp nào sẽ được giới thiệu trong hệ thống của bạn nơi bạn sẽ thay đổi từ Nhà máy trừu tượng thành Trình dựng?

Điểm của tôi là tôi không thể tìm thấy và ví dụ rõ ràng rằng một Nhà máy trừu tượng sẽ không đủ và bạn sẽ cần một Builder thay thế.

+1

+1 câu hỏi đầu tiên tuyệt vời Lino! Bạn nên nhảy thường xuyên hơn :-)! – KLE

+0

Cảm ơn, KLE. Nó vẫn còn làm phiền tôi, mặc dù :). Ý tôi là, nếu bạn đang xây dựng các đối tượng tổng hợp, và bạn lấy đạo diễn ra ngoài, truyền trách nhiệm gọi các phương thức xây dựng cho khách hàng, thì nó hoạt động cho tôi. Chỉ sau đó người xây dựng có vẻ hoàn toàn phù hợp. Nhưng với đạo diễn, nó dường như không nhiều ... –

+0

@Lino Chính xác, Trình tạo ** không có đạo diễn **, nó cho phép mỗi khách hàng tạo ra một sản phẩm phức tạp ** theo nhu cầu cụ thể **. Thông thường, không có hai khách hàng nào của một Builder sẽ xây dựng cùng một sản phẩm. Nếu nó là để tạo ra một người xây dựng phức tạp theo cách đóng gói và tái sử dụng (giám đốc), thì bạn có thể có một phương pháp để đóng gói này (và là "giám đốc" của bạn). Ngược lại, đối với ** AbstractFactory **, bạn thường cần một Giám đốc có thể tái sử dụng, ** tạo ra các sản phẩm giống nhau ** (được cung cấp với việc triển khai Nhà máy). – KLE

Trả lời

13

AbstractFactory dành cho gia đình các sản phẩm có liên quan. Trình xây dựng dành cho một sản phẩm.

Builder là để xây dựng một sản phẩm phức tạp từng bước, trong khi AbstractFactory là xây dựng một cách trừu tượng (có nghĩa là, một lần đối với một số triển khai) một sản phẩm ít phức tạp hơn.


Các ví dụ về những gì là sự khác biệt có nghĩa là mã gọi:

  • Để mã khách hàng sử dụng một AbstractFactory, mỗi lời gọi phương thức xây dựng một đối tượng. Khách hàng phải lắp ráp chúng lại với nhau. Ở phía bên kia, một người xây dựng sẽ lắp ráp chúng trong nội bộ, và cung cấp đồ thị đầy đủ đối tượng như là bước cuối cùng của tòa nhà.

  • Trình tạo cho phép chuyển và kiểm tra từng tham số cho mã máy khách. Nhưng anh ta có thể xây dựng sản phẩm cuối cùng trong một bước (ví dụ, một cuộc gọi đến một nhà xây dựng, truyền vào tất cả các tham số cùng một lúc, thậm chí cả các tham số phức tạp đã tự xây dựng). Vì vậy, sản phẩm của người xây dựng có thể là một đối tượng bất biến (hoặc đồ thị) (đó là vô giá trong môi trường đa luồng, vì lý do hiệu suất và bộ nhớ).


CẬP NHẬT để đáp ứng với nhận xét này:

Lino> Nó vẫn làm phiền tôi, mặc dù :). Ý tôi là, nếu bạn đang xây dựng các đối tượng tổng hợp, và bạn lấy đạo diễn ra ngoài, truyền trách nhiệm gọi các phương thức xây dựng cho khách hàng, thì nó hoạt động cho tôi. Chỉ sau đó người xây dựng có vẻ hoàn toàn phù hợp. Nhưng với đạo diễn, nó doens't có vẻ như nhiều ...

Chính xác, Builder không có giám đốc, nó cho phép mỗi khách hàng tạo ra một sản phẩm phức tạp theo đó là nhu cầu cụ thể. Khách hàng là giám đốc, bởi vì việc thực hiện của giám đốc không được sử dụng lại.

Nếu bạn cần tái sử dụng một vài lần quy trình xây dựng phức tạp, bạn có thể có phương pháp đóng gói (và phương pháp này là "đạo diễn").

Ngược lại, đối với các AbstractFactory, bạn thường cần một giám đốc thể tái sử dụng, đó là tạo ra sản phẩm như nhau (được cung cấp với một thực hiện Nhà máy).

+0

Chắc chắn một trong những mấu chốt của mô hình xây dựng là khả năng tái sử dụng đạo diễn. Một trong những ví dụ yêu thích của tôi về xây dựng là SAX, nơi một trình phân tích cú pháp có thể tái sử dụng (trình tạo) có thể được sử dụng với trình xử lý nội dung do người dùng cung cấp (trình tạo) để xây dựng một biểu diễn. Giám đốc và người xây dựng độc lập có thể tái sử dụng. –

2

Trình tạo hữu ích cho cấu hình. Abstract Factory rất hữu ích khi bạn không muốn người gọi quan tâm đến việc triển khai thực tế. Hai mục đích khác nhau.

Thực tế, bạn có thể kết hợp hai mẫu. Ví dụ: DocumentBuilderFactory của Java là một nhà máy trừu tượng cổ điển: nếu bạn đọc tài liệu, bạn sẽ thấy quy trình sử dụng để chọn triển khai. Tuy nhiên, DocumentBuilder s mà nó tạo ra có thể được cấu hình sau đó (mặc dù chúng không tuân theo phương pháp "xây dựng" nguyên mẫu của việc có mỗi phương thức cấu hình trả về đối tượng đang được cấu hình).

1

Tôi sử dụng Nhà máy trừu tượng khi tôi cần xây dựng nhiều nhà máy trẻ em để tạo các loại đối tượng khác nhau. Các nhà máy trẻ em này đều thực hiện hoặc mở rộng Nhà máy Trừu tượng. Tôi sử dụng một Builder khi chỉ có một loại đối tượng cần được xây dựng.

Tôi không chắc liệu đây có phải là cách sử dụng đúng hay không, nhưng đó là cách tôi đã xem nó và cách tôi đã thực hiện nó trong quá khứ.

4

Một ví dụ điển hình mà bạn muốn một người xây dựng là nếu bạn xây dựng một thứ gì đó từng mảnh dựa trên các đối số dòng lệnh. Ví dụ: hãy xem xét người xây dựng có các phương pháp như ...

setName() 
setType() 
setOption() 

Người xây dựng cũng có thể được kết hợp với nhà máy trừu tượng nơi giám đốc yêu cầu nhà máy sản phẩm cụ thể. Một lần nữa, điều này có thể được thực hiện chỉ với một mẫu nhà máy bằng cách chuyển danh sách args tới nhà máy, nhưng điều gì sẽ xảy ra nếu các arg thay vào đó là các thông điệp đến từ một máy chủ hoặc một máy khách.

Thỉnh thoảng tính thẩm mỹ của một mẫu vừa phù hợp đẹp hơn tính thẩm mỹ của loại kia.

+0

"Một lần nữa, điều này có thể được thực hiện chỉ với một mẫu nhà máy bằng cách chuyển danh sách args tới nhà máy, nhưng nếu các arg thay vì thông điệp đến từ máy chủ hoặc máy khách." Nhưng sau đó trách nhiệm gọi các phương thức sáng tạo trên các nhà xây dựng (setName, setType ...) sẽ được chuyển giao cho khách hàng, phải không? Và để làm việc đó, các thuộc tính phóng viên của các lớp được tạo ra sẽ phải là tùy chọn hoặc bạn sẽ tạo ra một đối tượng không nhất quán. Tôi bắt đầu nghĩ rằng đó là nơi người xây dựng tỏa sáng: khi bạn chuyển trách nhiệm cho khách hàng và các thuộc tính là tùy chọn –

+0

Điều đó không đúng. Sự hiểu biết của tôi về mô hình Builder là bạn có một giám đốc (thuật toán xây dựng) mà làm cho tất cả các cuộc gọi đến người xây dựng (tạo ra các đại diện đối tượng) cho khách hàng. Khách hàng có thể chọn người xây dựng hoặc sử dụng một nhà máy để làm cho nó sau đó chuyển cho giám đốc. Sau đó, nó sẽ chỉ gọi một phương pháp trên giám đốc đi qua trong tất cả các dữ liệu. Ví dụ tôi tin rằng cuốn sách Gang of Four được sử dụng đã chuyển đổi một tài liệu sang các định dạng khác nhau. Ngoài ra tôi không nghĩ rằng sự phức tạp của đối tượng nhất thiết phải tách biệt nhà máy và mô hình xây dựng. –

7

Một số câu trả lời rất hay ở đây. Tôi chỉ cung cấp một sự tương tự.

Giả sử bạn muốn có bàn làm việc mới cho văn phòng mới của mình. Bạn đi đến 'nhà máy' và xem các lựa chọn rồi chọn một trong các giá. Nếu nó phù hợp với nhu cầu của bạn, tuyệt vời!

Bây giờ bạn có một văn phòng lớn hơn với các bức tường có hình dạng thực sự lạ mắt. Bây giờ bạn cần một chiếc bàn có hình trên cùng để phù hợp với văn phòng của bạn. Và bạn muốn có một đôi chân khác nhau để phù hợp với phần còn lại của đồ nội thất và cũng để phù hợp với chiếc ghế Aeron mới của bạn.

Bạn quay lại cùng một nhà máy, không may mắn. Bạn đi đến một thợ mộc có thể tùy chỉnh 'xây dựng' những gì bạn muốn. Bạn cung cấp thông số kỹ thuật và yêu cầu của bạn và 'người xây dựng' sẽ cho bạn biết những hạn chế nhất định. Sau một vài lần lặp lại, bạn có bàn hoàn hảo!

Ok, một câu chuyện què quặt nhưng chỉ để làm sáng mọi thứ: P

2

Trình xây dựng đảo ngược kiểm soát, như Mẫu phương pháp mẫu. Các chức năng khác nhau trên công cụ xây dựng bê tông của bạn là các bước có thể tùy chỉnh trong quy trình. Tóm tắt Nhà máy là "chỉ" đa hình, nơi đầu ra xảy ra là một đối tượng mới được xây dựng. Các chức năng khác nhau trên một nhà máy cụ thể là các quy trình tùy biến khác nhau, mỗi quy trình có thể dẫn đến một đối tượng khác. Vì vậy, bạn cần một người xây dựng khi bạn cần có một "cốt truyện chung" chung để xây dựng các đối tượng của bạn, nhưng với "cảnh" riêng biệt trong cốt truyện đó là khác nhau. Bạn cần một nhà máy khi không nhất thiết phải có bất cứ điều gì chung giữa các triển khai khác nhau.

Tôi nghĩ bạn có thể sử dụng đồng thời cả hai cùng một lúc, với Nhà máy Tóm tắt đóng vai trò giám đốc trong mẫu Builder và mỗi nhà máy cụ thể chỉ đạo mọi thứ khác nhau. Tuy nhiên, đó vượt xa những "khăn ăn" giới hạn cho sơ đồ UML ;-)

0

Để biết thêm thông tin về khi sử dụng các mẫu Builder và lợi thế của mình bạn nên kiểm tra bài của tôi cho một câu hỏi tương tự here

1

Hãy xem xét sự tương tự.

Bạn đang ở một chuỗi thức ăn nhanh, nơi thức ăn nhanh mà bạn thực sự nhận được khá phức tạp. Không chỉ phức tạp, nhưng chỉ một số người có thể nhận đơn đặt hàng của bạn cho một số loại thực phẩm nhất định. Bây giờ, bạn không biết điều đó, bởi vì người quản lý cửa hàng quyết định đặt một người đứng sau một máy tính tiền. Nhưng nếu bạn xem xét cẩn thận, đó thực sự là hình ba chiều nâng cao vì đó là "trừu tượng". Một người đặt hàng trừu tượng. Bây giờ, khi bạn nói chuyện với hình ba chiều, và đặt hàng của bạn, máy tính ba chiều định tuyến lại (đa hình) để đặt vào một bộ cấy trong não của một người đặt hàng. Cấy ghép làm cho con người thực sự đấm theo thứ tự để đăng ký thực sự. Có ít trong số "bê tông" những con người được kiểm soát tâm trí này được đặt hàng bởi hình ba chiều. Bây giờ, khi con người thực sự đấm theo thứ tự, nó được gửi đến một máy tính ở phía sau, nơi có một dây chuyền lắp ráp, hoặc một người xây dựng "", cho mỗi loại thực phẩm được xây dựng. Các đơn đặt hàng được gửi đến các loại dây chuyền lắp ráp khác nhau dựa trên con người và máy tính tiền của họ.

Vì vậy, hình ba chiều là nhà máy trừu tượng, con người kiểm soát tâm trí tại sổ đăng ký là các nhà máy cụ thể và các dây chuyền lắp ráp là những người xây dựng. Đây là cách bạn thực sự có thể hình dung luồng của một nhà máy trừu tượng đang hoạt động VỚI mẫu trình tạo. Đôi khi tốt nhất là xem cách các mẫu thiết kế hoạt động cùng nhau để xem chúng khác nhau như thế nào.

Nếu bạn đang tìm kiếm thêm tín dụng, hãy thử triển khai tính năng này bằng Generics. Nó không đòi hỏi nhiều mã như bạn nghĩ.

0

Trong thực tế, bạn có thể sử dụng DI + IOC để làm những gì người xây dựng thường làm. FYI.

+1

DI và IOC có nghĩa là cho mục đích khác nhau - cho khớp nối lỏng lẻo. nơi Builder cung cấp một giao diện để tạo các đối tượng phức tạp với các biểu diễn khác nhau. – Brainchild

0

Câu trả lời hay, muốn thêm tôi vào hy vọng tôi khám phá ra rằng sự hiểu biết của tôi là chính xác.

Nếu bạn có văn phòng mới và chỉ cần bàn mới, bạn sẽ sử dụng Trình tạo. Bàn làm việc sẽ luôn là bàn làm việc, nhưng có nhiều cấu hình khác nhau cho bàn làm việc, ví dụ, kích thước, hình dạng, sự hiện diện của hutch, ngăn kéo, v.v.

Nếu bạn có văn phòng mới và bên trong hoàn toàn trống , bạn sẽ cần các đối tượng khác nhau và sẽ sử dụng một Nhà máy Tóm tắt tạo ra Đồ nội thất, từ đó Bàn của chúng tôi sẽ hạ xuống. Trong trường hợp này, Desk như chúng ta biết là một đối tượng "phức tạp", vì vậy nó sử dụng mẫu Builder, nhưng ở đây nó là một phần của một Abstract Factory trực tiếp. Nhà máy Tóm tắt cũng sẽ tạo ra các đối tượng đơn giản, giống như các đèn rất cụ thể (StraightFunkyLamp), thông qua một lớp StraightFunkyLampFactory.

Các vấn đề liên quan