Hiểu sự khác biệt trong các động lực:
Giả sử bạn đang xây dựng một công cụ trong đó bạn có các đối tượng và triển khai cụ thể các mối tương quan của các đối tượng. Vì bạn thấy trước các biến thể trong các đối tượng, bạn đã tạo ra một sự gián tiếp bằng cách giao trách nhiệm tạo các biến thể của các đối tượng cho một đối tượng khác ( chúng tôi gọi đó là nhà máy trừu tượng ). Sự trừu tượng hóa này tìm thấy lợi ích mạnh mẽ vì bạn thấy trước các tiện ích mở rộng trong tương lai cần các biến thể của các đối tượng đó.
Một động lực khá hấp dẫn khác trong dòng suy nghĩ này là một trường hợp trong đó mọi hoặc không ai trong số các đối tượng trong toàn nhóm sẽ có một biến thể tương ứng. Dựa trên một số điều kiện, một trong hai biến thể sẽ được sử dụng và trong mỗi trường hợp, tất cả các đối tượng phải có cùng một biến thể. Điều này có thể hơi phản cảm để hiểu vì chúng ta thường nghĩ rằng - miễn là các biến thể của một đối tượng tuân theo một hợp đồng thống nhất chung ( giao diện theo nghĩa rộng hơn ), mã thực thi cụ thể sẽ không bao giờ bị phá vỡ. Một sự thật thú vị ở đây là, không phải lúc nào điều này cũng đúng, đặc biệt khi hành vi dự kiến không thể được mô hình hóa bằng một hợp đồng lập trình.
Một điều đơn giản ( mượn ý tưởng từ GoF ) là bất kỳ ứng dụng GUI nào nói rằng một màn hình ảo mô phỏng giao diện của MS hoặc Mac hoặc Fedora OS. Ở đây, ví dụ, khi tất cả các đối tượng widget như cửa sổ, nút, v.v. đều có biến thể MS ngoại trừ thanh cuộn có nguồn gốc từ biến thể MAC, mục đích của công cụ thất bại nặng nề.
Những trường hợp trên tạo thành nhu cầu cơ bản của Mẫu nhà máy trừu tượng .
Mặt khác, hãy tưởng tượng bạn đang viết một khung để nhiều người có thể xây dựng các công cụ khác nhau ( chẳng hạn như một trong các ví dụ trên ) bằng cách sử dụng khung của bạn. Theo ý tưởng của một khung công tác, bạn không cần, mặc dù bạn không thể sử dụng các đối tượng cụ thể trong logic của mình. Bạn thay vì đặt một số hợp đồng cấp cao giữa các đối tượng khác nhau và cách chúng tương tác. Mặc dù bạn ( với tư cách là nhà phát triển khung ) vẫn ở mức rất trừu tượng, mỗi người xây dựng công cụ buộc phải tuân theo các cấu trúc khung của bạn. Tuy nhiên, họ ( những người xây dựng công cụ ) có quyền tự do quyết định đối tượng nào sẽ được xây dựng và cách tất cả các đối tượng họ tạo sẽ tương tác. Không giống như trường hợp trước ( của Mẫu nhà máy trừu tượng ), bạn ( với tư cách là người tạo khung) không cần phải làm việc với các đối tượng cụ thể trong trường hợp này; và thay vào đó có thể ở mức hợp đồng của các đối tượng. Hơn nữa, không giống như phần thứ hai của các động lực trước đó, bạn hoặc người xây dựng công cụ không bao giờ có tình huống trộn các đối tượng từ các biến thể. Ở đây, trong khi mã khung vẫn ở mức hợp đồng, mọi nhà xây dựng công cụ bị hạn chế ( theo bản chất của trường hợp ) đối với việc sử dụng các đối tượng của riêng họ. Các sáng tạo đối tượng trong trường hợp này được ủy quyền cho mỗi người triển khai và các nhà cung cấp khung chỉ cung cấp các phương thức thống nhất để tạo và trả về các đối tượng. Các phương thức như vậy là không thể tránh khỏi đối với nhà phát triển khung để tiến hành mã của họ và có một tên đặc biệt gọi là Phương thức Factory ( Mẫu phương thức nhà máy cho mẫu bên dưới ).
Một số lưu ý:
- Nếu bạn quen thuộc với 'phương thức mẫu', thì bạn sẽ thấy rằng các phương thức xuất xưởng thường được gọi từ các phương thức mẫu trong trường hợp các chương trình liên quan đến bất kỳ dạng khung nào. Ngược lại, các phương thức mẫu của các chương trình ứng dụng thường đơn giản là thực hiện thuật toán cụ thể và làm mất hiệu lực của các phương thức xuất xưởng.
- Hơn nữa, để hoàn thiện các ý nghĩ, sử dụng khung ( đã đề cập ở trên ), khi người xây dựng công cụ đang xây dựng một công cụ, bên trong mỗi phương thức của nhà máy, thay vì tạo một đối tượng cụ thể, anh ta / cô ta có thể giao thêm trách nhiệm cho một bản tóm tắt đối tượng -factory, được cung cấp trình xây dựng công cụ dự đoán các biến thể của các đối tượng cụ thể cho các phần mở rộng trong tương lai.
Mã mẫu:
//Part of framework-code
BoardGame {
Board createBoard() //factory method. Default implementation can be provided as well
Piece createPiece() //factory method
startGame(){ //template method
Board borad = createBoard()
Piece piece = createPiece()
initState(board, piece)
}
}
//Part of Tool-builder code
Ludo inherits BoardGame {
Board createBoard(){ //overriding of factory method
//Option A: return new LudoBoard() //Lodu knows object creation
//Option B: return LudoFactory.createBoard() //Lodu asks AbstractFacory
}
….
}
//Part of Tool-builder code
Chess inherits BoardGame {
Board createBoard(){ //overriding of factory method
//return a Chess board
}
….
}