Tại sao mẫu thiết kế phương thức nhà máy hữu ích hơn việc có các lớp và gọi chúng riêng lẻ?


32

Từ các mẫu thiết kế "Gang of Four", có phương pháp Factory:

class Factory(product)
  case product
  when a
    new A
  when b
    new B
  when c
    new C
end

new Factory(a)

Tại sao điều này có ích hơn có ba lớp, a, b, và cgọi họ là cá nhân?


1
Ý bạn là gì? Tại sao không khởi tạo cả ba? Đó có phải là ý bạn không?
Neil

1
@Neil Không, trong mẫu nhà máy tất cả các lớp tồn tại như anh em ruột thịt. Tại sao gọi nhà máy để gián tiếp truy cập các lớp a, b, c?
alt

3
điều này thực sự không giống với mô hình phương thức nhà máy đối với tôi, nếu bất cứ điều gì nó gần với nhà máy trừu tượng hơn
jk.

2
Bởi vì tại thời điểm thiết kế, bạn không biết lớp nào trong 3 lớp bạn cần khởi tạo.
MrWhite

2
@jk: Không, nó thực sự không. lập trình
viên.stackexchange.com/questions /81838 / Ấn

Câu trả lời:


54

Bởi vì ví dụ của bạn không đủ phức tạp. Đối với một kịch bản đơn giản như vậy, thậm chí không có ý nghĩa gì khi sử dụng một mẫu nâng cao.

Nhưng nếu bạn phải biết nhiều hơn sản phẩm để xây dựng A, B hoặc C và bạn không thể truy cập trực tiếp vào kiến ​​thức đó, thì nó rất hữu ích. Sau đó, bạn đang sử dụng nhà máy để hoạt động như một trung tâm kiến ​​thức để sản xuất các đối tượng cần thiết.

Có thể các đối tượng đó cần tham chiếu đến một số đối tượng X mà nhà máy có thể cung cấp, nhưng mã của bạn ở nơi bạn muốn xây dựng A, B hoặc C không thể hoặc không nên truy cập vào X. Có thể khi bạn có X bạn tạo A và B nhưng nếu bạn có kiểu Y thì bạn tạo C.

Cũng xem xét rằng một số đối tượng có thể cần 20 phụ thuộc để tạo; sau đó thì sao Đi săn những phụ thuộc đó ở một nơi không thể truy cập được có thể là vấn đề.


13
+1 để làm rõ rằng mô hình Factory không phải lúc nào cũng là cách tiếp cận tốt nhất.
Neil

1
Bởi vì ví dụ của bạn không đủ phức tạp. Đối với một kịch bản đơn giản như vậy, thậm chí không có ý nghĩa gì khi sử dụng một mẫu nâng cao. Vậy bạn sẽ làm gì trong trường hợp này? Nội tuyến xây dựng có điều kiện?
pdr

Nó có thể chỉ là phương thức lấy sản phẩm và trả về những gì bạn cần để làm cho nó có thể tái sử dụng, vì vậy nó không phải là nội tuyến. Nếu phương thức như vậy phát triển thành một cái gì đó lớn hơn, hoặc được sử dụng trong một số lớp khác, bạn có thể cấu trúc lại nó thành lớp khác.
Mateusz

Các mô hình được gọi là Phương pháp nhà máy cho một lý do. Phương thức này không phải thuộc một lớp khác để trở thành Phương thức xuất xưởng (mặc dù nó thường như vậy).
pdr

Tôi đã bỏ lỡ "Phương pháp" trong đó, vì vậy bạn là người đúng.
Mateusz

23

Một mô hình nhà máy thường phức tạp hơn thế. Một nhà máy quyết định các tiêu chí nhất định để tạo / trả lại. Thay vào đó, khi bạn không sử dụng nhà máy, bạn sẽ có mã đó được sử dụng nhiều lần ở một số vị trí trong mã của bạn.

Ví dụ, hãy xem xét các vấn đề sau: bạn cần tải dữ liệu từ DB, nhưng bạn có một DB trung tâm để tích hợp với nhiều dữ liệu và một dữ liệu nhỏ hơn trong bộ nhớ trên mỗi dev-PC. Trong mã của bạn, bạn yêu cầu một nhà máy lấy một tay cầm DB và nhà máy trả về một trong những cái đó tùy thuộc vào ví dụ như một tệp cấu hình.


20

Mẫu Phương thức nhà máy trừu tượng hóa quá trình ra quyết định từ lớp gọi. Điều này có một số lợi thế:

Tái sử dụng. Nếu tôi muốn khởi tạo ở nhiều nơi, tôi không phải lặp lại tình trạng của mình, vì vậy khi tôi đến để thêm một lớp mới, tôi sẽ không có nguy cơ bỏ lỡ một lớp.

Kiểm tra đơn vị. Tôi có thể viết 3 bài kiểm tra cho nhà máy, để đảm bảo nó trả về các loại đúng với các điều kiện chính xác, sau đó lớp gọi của tôi chỉ cần được kiểm tra để xem nếu nó gọi nhà máy và sau đó là các phương thức cần thiết trên lớp trả về. Nó cần biết gì về việc thực hiện chính nhà máy hoặc các lớp cụ thể.

Khả năng mở rộng. Khi ai đó quyết định chúng ta cần thêm một lớp D mới vào nhà máy này, không có mã gọi nào, không phải kiểm tra đơn vị hoặc thực hiện, không cần phải nói. Chúng tôi chỉ cần tạo một lớp D mới và mở rộng phương thức xuất xưởng của chúng tôi. Đây là định nghĩa của Nguyên tắc Đóng-Đóng .

Bạn thậm chí có thể tạo một lớp nhà máy mới và làm cho chúng có thể hoán đổi được, nếu tình huống yêu cầu - ví dụ, nếu bạn muốn có thể bật và tắt lớp D trong khi thử nghiệm. Tôi đã gặp tình huống này chỉ một lần, nhưng nó cực kỳ hữu ích.

Như đã nói, Mô hình nhà máy không phải lúc nào cũng đi. Nhưng, bất cứ nơi nào bạn thấy khởi tạo có điều kiện, bạn nên cho nó một chút suy nghĩ.


14

Những lợi thế chính của mẫu Factory là gấp đôi:

  1. Những nơi cần triển khai sản phẩm không cần biết cách xây dựng. Nhà máy giữ thông tin đó.

    Bạn có muốn biết những đối số nào để truyền cho hàm tạo cụ thể không? Hoặc những gì phụ thuộc bạn phải tiêm? Hoặc làm thế nào để đăng ký lớp thực hiện với cơ sở dữ liệu sau khi nó được cấu hình đầy đủ? Không? Hãy để nhà máy chăm sóc tất cả những thứ đó.

  2. Những nơi cần triển khai sản phẩm không cần biết tại thời điểm mô tả mô-đun (tức là tại thời điểm biên dịch) tên của lớp thực hiện là gì.

    Như vậy, akhông cần phải làm gì cả A; những gì mà xây dựng thành công có thể được mô tả theo các đặc tính phi chức năng mong muốn và không chỉ là tên. Điều này linh hoạt hơn nhiều.

Nhược điểm là nơi bạn biết phải làm gì và làm như thế nào, bạn sẽ trở nên phức tạp hơn khi bạn sử dụng một nhà máy. Cách khắc phục rất đơn giản: đừng sử dụng nhà máy khi nó không có ý nghĩa!


2

Tôi muốn nghĩ về các mẫu thiết kế theo các lớp là "người" và các mẫu là cách mọi người nói chuyện với nhau.

Vì vậy, với tôi mô hình nhà máy giống như một công ty tuyển dụng. Bạn đã có ai đó sẽ cần một số lượng công nhân khác nhau. Người này có thể biết một số thông tin họ cần ở những người họ thuê, nhưng đó là thông tin đó.

Vì vậy, khi họ cần một nhân viên mới, họ gọi cho cơ quan tuyển dụng và nói với họ những gì họ cần. Bây giờ, để thực sự thuê một ai đó, bạn cần biết rất nhiều thứ - lợi ích, xác minh đủ điều kiện, v.v. Nhưng người tuyển dụng không cần biết bất kỳ điều gì trong số này - cơ quan tuyển dụng xử lý tất cả những điều đó.

Theo cách tương tự, sử dụng Factory cho phép người tiêu dùng tạo các đối tượng mới mà không cần phải biết chi tiết về cách họ tạo ra hoặc phụ thuộc của họ là gì - họ chỉ phải cung cấp thông tin họ thực sự muốn.

Phép lịch sự


1

Mẫu Factory là mẫu thiết kế bị lạm dụng và lạm dụng nhiều nhất.

Tôi đã gặp rất nhiều trường hợp trong đó một lớp Factory được mã hóa khi một hàm tạo đơn giản sẽ đầy đủ.

Không sử dụng lớp nhà máy trừ khi: -

  • Bạn phụ thuộc vào tài nguyên bên ngoài nhưng bạn chưa biết chính xác tài nguyên nào.
  • Xây dựng là tốn kém và bạn muốn xây dựng một lần và tái sử dụng nhiều lần.
  • Xây dựng một thể hiện mới phụ thuộc vào những trường hợp nào đã được xây dựng (ví dụ: Bạn chỉ có thể có năm kết nối, hoặc, bạn nên sử dụng số id kết nối nhiều hơn số cuối được sử dụng).

0

Sử dụng Phương thức nhà máy khi khởi tạo một lớp con và mã máy khách không có trách nhiệm quyết định lớp con cụ thể nào được khởi tạo.

Nó rất hữu ích vì nó ngăn bạn khỏi phải thay đổi mã máy khách khi bạn cần thay đổi lớp nào được khởi tạo. Thay đổi mã hiện tại là thực tế xấu vì nó thường dễ bị lỗi.

Một ví dụ sẽ có các lớp con, trong đó mỗi lớp sắp xếp dữ liệu theo thứ tự tăng dần, nhưng theo một cách khác nhau. Mỗi cách là tối ưu cho một loại dữ liệu cụ thể. ví dụ: dữ liệu được sắp xếp một phần, dữ liệu là số, v.v. Mã khách là lớp chỉ xử lý in dữ liệu. Có mã quyết định lớp sắp xếp nào được khởi tạo trong lớp máy khách sẽ làm cho nó trở thành một lớp phức tạp. Nói cách khác, có nhiều hơn một trách nhiệm, trong trường hợp này, quyết định lớp sắp xếp nào là tối ưu và in dữ liệu. Bằng cách đặt mã quyết định lớp sắp xếp nào được khởi tạo vào lớp Factory, nó phân tách các mối quan tâm để bạn không cần thay đổi lớp máy khách mỗi khi bạn cần thay đổi lớp sắp xếp nào được khởi tạo.

Đó là một cách che mông của bạn, nếu bạn có thể thấy trước những thay đổi tự thực hiện của mình theo cách thức hoặc lớp nào được khởi tạo thì lớp nhà máy có ý nghĩa để sử dụng. Nó giúp giữ cho các lớp của bạn tập trung vào một trách nhiệm của họ và kết quả là đảm bảo rằng bạn ít có khả năng phải sửa đổi mã hiện tại không liên quan.

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.