Завдання в моєму інженерному класі програмного забезпечення - розробити додаток, який може грати в різні форми певної гри. Гра, про яку йдеться, - Манкала, деякі з цих ігор називаються Варі або Кала. Ці ігри відрізняються в деяких аспектах, але для мого питання важливо лише знати, що ігри можуть відрізнятися в наступному:
- Спосіб обробки результату переміщення
- Спосіб визначення кінця гри
- Спосіб визначення переможця
Перше, що мені прийшло в голову розробити це, - це використовувати шаблон стратегії, у мене є варіація алгоритмів (власне правила гри). Дизайн може виглядати приблизно так:
Тоді я подумав собі, що в грі Манкала та Варі спосіб визначення переможця точно такий же, і код буде дублюватися. Я не думаю, що це, за визначенням, порушення принципу «одне правило, одне місце» або DRY, оскільки сприйняття змін у правилах для Mancala не означає автоматично, що це правило слід змінювати і у Wari. Тим не менш, з відгуків, отриманих від мого професора, у мене склалося враження знайти інший дизайн.
Потім я придумав це:
Кожна гра (Mancala, Wari, Kalah, ...) просто матиме атрибут типу інтерфейсу кожного правила, тобто, WinnerDeterminer
якщо є версія Mancala 2.0, яка є такою ж, як Mancala 1.0, за винятком того, як визначається переможець, він може просто використовувати версії Mancala.
Я вважаю, що реалізація цих правил як структури стратегії, безумовно, справедлива. Але справжня проблема виникає тоді, коли я хочу її розробити далі.
Читаючи про шаблон шаблону методу, я одразу подумав, що його можна застосувати до цієї проблеми. Дії, які виконуються, коли користувач робить крок, завжди однакові і в тому ж порядку, а саме:
- закладайте камені в отвори (це однаково для всіх ігор, тому це було б реалізовано в самому методі шаблону)
- визначте результат переїзду
- визначте, чи закінчилась гра через попередній хід
- якщо гра закінчена, визначте, хто переміг
Ці три останні кроки - це все в моїй стратегії, описаній вище. У мене багато проблем, поєднуючи ці два. Одним з можливих варіантів рішення було б відмовитися від стратегії та зробити наступне:
Я насправді не бачу різниці в дизайні між схемою стратегії та цією? Але я впевнений, що мені потрібно використовувати шаблонний метод (хоча я був так само впевнений, що потрібно використовувати шаблон стратегії).
Я також не можу визначити, хто буде нести відповідальність за створення TurnTemplate
об'єкта, тоді як за схемою стратегії я відчуваю, що у мене є сім'ї об'єктів (три правила), які я міг би легко створити, використовуючи абстрактний заводський зразок. Потім у мене з'явиться а MancalaRuleFactory
, WariRuleFactory
і т. Д., І вони створюють правильні екземпляри правил і передають мені RuleSet
об'єкт.
Скажімо, я використовую стратегію + абстрактний заводський візерунок і в мене є RuleSet
об'єкт, який має алгоритми для трьох правил у ньому. Єдиний спосіб, коли я можу все-таки використовувати шаблон шаблону методу для цього, - це передавати цей RuleSet
об’єкт своєму TurnTemplate
. «Проблема», що виникає тоді, полягає в тому, що мені ніколи не знадобляться мої конкретні реалізації TurnTemplate
цих класів, вони б застаріли. У моїх захищених методах в TurnTemplate
я міг просто зателефонувати ruleSet.determineWinner()
. Як наслідок, TurnTemplate
клас більше не буде абстрактним, а повинен стати конкретним, чи тоді це все ще шаблон шаблону методу?
Підводячи підсумок, я думаю правильно чи пропускаю щось легке? Якщо я перебуваю на правильному шляху, як можна поєднати шаблон стратегії та шаблон шаблону?