Một nhiệm vụ trong lớp kỹ thuật phần mềm của tôi là thiết kế một ứng dụng có thể chơi các dạng khác nhau của một trò chơi cụ thể. Trò chơi trong câu hỏi là Mancala, một số trò chơi này được gọi là Wari hoặc Kalah. Các trò chơi này khác nhau ở một số khía cạnh nhưng đối với câu hỏi của tôi, điều quan trọng chỉ cần biết là các trò chơi có thể khác nhau như sau:
- Cách xử lý kết quả của việc di chuyển
- Cách xác định kết thúc trò chơi
- Cách xác định người chiến thắng
Điều đầu tiên tôi nghĩ đến khi thiết kế nó là sử dụng mô hình chiến lược, tôi có một biến thể trong các thuật toán (quy tắc thực tế của trò chơi). Thiết kế có thể trông như thế này:

Sau đó tôi tự nghĩ rằng trong trò chơi Mancala và Wari, cách người chiến thắng được xác định là hoàn toàn giống nhau và mã sẽ được sao chép. Tôi không nghĩ rằng điều này theo định nghĩa là vi phạm nguyên tắc 'một quy tắc, một nơi' hoặc DRY được coi là thay đổi quy tắc cho Mancala sẽ không tự động có nghĩa là quy tắc đó cũng nên được thay đổi trong Wari. Tuy nhiên, từ phản hồi tôi nhận được từ giáo sư của mình, tôi đã có ấn tượng để tìm một thiết kế khác.
Sau đó tôi đã nghĩ ra điều này:

Mỗi trò chơi (Mancala, Wari, Kalah, ...) sẽ chỉ có thuộc tính loại giao diện của từng quy tắc, WinnerDeterminervà nếu có phiên bản Mancala 2.0 giống với Mancala 1.0 ngoại trừ cách xác định người chiến thắng thì có thể sử dụng các phiên bản Mancala.
Tôi nghĩ rằng việc thực hiện các quy tắc này như một mô hình chiến lược chắc chắn là hợp lệ. Nhưng vấn đề thực sự đến khi tôi muốn thiết kế nó hơn nữa.
Khi đọc về mẫu phương thức mẫu, tôi nghĩ ngay lập tức nó có thể được áp dụng cho vấn đề này. Các hành động được thực hiện khi người dùng thực hiện di chuyển luôn giống nhau và theo cùng một thứ tự, cụ thể là:
- gửi đá vào lỗ (điều này giống nhau cho tất cả các trò chơi, do đó sẽ được thực hiện trong chính phương thức mẫu)
- xác định kết quả của việc di chuyển
- xác định xem trò chơi đã kết thúc vì di chuyển trước đó chưa
- nếu trò chơi kết thúc, hãy xác định ai đã thắng
Ba bước cuối cùng là tất cả trong mô hình chiến lược của tôi được mô tả ở trên. Tôi đang gặp nhiều rắc rối khi kết hợp cả hai. Một giải pháp khả thi tôi tìm thấy là từ bỏ mô hình chiến lược và thực hiện như sau:

Tôi không thực sự thấy sự khác biệt về thiết kế giữa mẫu chiến lược và cái này? Nhưng tôi chắc chắn rằng tôi cần sử dụng một phương thức mẫu (mặc dù tôi chắc chắn về việc phải sử dụng một mẫu chiến lược).
Tôi cũng không thể xác định ai sẽ chịu trách nhiệm tạo TurnTemplateđối tượng, trong khi với mẫu chiến lược tôi cảm thấy tôi có các họ đối tượng (ba quy tắc) mà tôi có thể dễ dàng tạo bằng mô hình nhà máy trừu tượng. Sau đó tôi sẽ có một MancalaRuleFactory, WariRuleFactoryv.v. và họ sẽ tạo ra các thể hiện chính xác của các quy tắc và trao lại cho tôi một RuleSetđối tượng.
Giả sử tôi sử dụng chiến lược + mẫu nhà máy trừu tượng và tôi có một RuleSetđối tượng có thuật toán cho ba quy tắc trong đó. Cách duy nhất tôi cảm thấy tôi vẫn có thể sử dụng mẫu phương thức mẫu với điều này là truyền RuleSetđối tượng này cho tôi TurnTemplate. "Vấn đề" mà sau đó nổi lên là tôi sẽ không bao giờ cần các triển khai cụ thể của mình TurnTemplate, các lớp này sẽ trở nên lỗi thời. Trong các phương thức được bảo vệ của tôi trong TurnTemplatetôi chỉ có thể gọi ruleSet.determineWinner(). Kết quả là, TurnTemplatelớp sẽ không còn trừu tượng mà sẽ phải trở nên cụ thể, liệu nó có còn là một mẫu phương thức mẫu không?
Tóm lại, tôi đang suy nghĩ đúng cách hay tôi đang thiếu một cái gì đó dễ dàng? Nếu tôi đang đi đúng hướng, làm cách nào để kết hợp một mẫu chiến lược và một mẫu phương thức mẫu?