Une tâche dans ma classe de génie logiciel est de concevoir une application qui peut jouer différentes formes d'un jeu particulier. Le jeu en question est Mancala, certains de ces jeux sont appelés Wari ou Kalah. Ces jeux diffèrent sur certains aspects, mais pour ma question, il est seulement important de savoir que les jeux peuvent différer de la manière suivante:
- La façon dont le résultat d'un déménagement est géré
- La façon dont la fin de la partie est déterminée
- La façon dont le gagnant est déterminé
La première chose qui m'est venue à l'esprit pour concevoir ceci était d'utiliser le modèle de stratégie, j'ai une variation dans les algorithmes (les règles réelles du jeu). Le design pourrait ressembler à ceci:
Je me suis alors dit que dans le jeu de Mancala et Wari, la façon dont le gagnant est déterminé est exactement la même et le code serait dupliqué. Je ne pense pas que ce soit par définition une violation du principe `` une règle, un seul endroit '' ou DRY, car un changement dans les règles pour Mancala ne signifierait pas automatiquement que la règle devrait également être modifiée dans Wari. Néanmoins, grâce aux commentaires de mon professeur, j'ai eu l'impression de trouver un design différent.
J'ai ensuite trouvé ceci:
Chaque jeu (Mancala, Wari, Kalah, ...) aurait juste un attribut du type d'interface de chaque règle, c'est WinnerDeterminer
-à- dire et s'il y a une version Mancala 2.0 qui est la même que Mancala 1.0 sauf pour la façon dont le gagnant est déterminé, il peut simplement utilisez les versions de Mancala.
Je pense que la mise en œuvre de ces règles en tant que modèle de stratégie est certainement valable. Mais le vrai problème vient quand je veux le concevoir davantage.
En lisant sur le modèle de méthode de modèle, j'ai immédiatement pensé qu'il pouvait être appliqué à ce problème. Les actions effectuées lorsqu'un utilisateur effectue un mouvement sont toujours les mêmes et dans le même ordre, à savoir:
- déposer des pierres dans des trous (c'est le même pour tous les jeux, donc serait implémenté dans la méthode du modèle elle-même)
- déterminer le résultat du déménagement
- déterminer si le jeu est terminé à cause du coup précédent
- si le jeu est terminé, déterminez qui a gagné
Ces trois dernières étapes sont toutes dans mon modèle de stratégie décrit ci-dessus. J'ai beaucoup de mal à combiner ces deux. Une solution possible que j'ai trouvée serait d'abandonner le modèle de stratégie et de faire ce qui suit:
Je ne vois pas vraiment la différence de conception entre le modèle de stratégie et celui-ci? Mais je suis certain que je dois utiliser une méthode de modèle (bien que j'étais tout aussi sûr d'avoir à utiliser un modèle de stratégie).
Je ne peux pas non plus déterminer qui serait responsable de la création de l' TurnTemplate
objet, alors qu'avec le modèle de stratégie, j'ai le sentiment d'avoir des familles d'objets (les trois règles) que je pourrais facilement créer en utilisant un modèle d'usine abstrait. Je puis un MancalaRuleFactory
, WariRuleFactory
, etc. , et ils créeraient les instances correcte des règles et la main - moi un RuleSet
objet.
Disons que j'utilise le modèle de stratégie + usine abstraite et que j'ai un RuleSet
objet qui contient des algorithmes pour les trois règles. La seule façon dont je sens que je peux encore utiliser le modèle de méthode de modèle avec ceci est de passer cet RuleSet
objet à mon TurnTemplate
. Le «problème» qui fait alors surface est que je n'aurais jamais besoin de mes implémentations concrètes de la TurnTemplate
, ces classes deviendraient obsolètes. Dans mes méthodes protégées dans le TurnTemplate
je pourrais simplement appeler ruleSet.determineWinner()
. En conséquence, la TurnTemplate
classe ne serait plus abstraite mais devrait devenir concrète, s'agit-il alors encore d'un modèle de méthode modèle?
Pour résumer, est-ce que je pense dans le bon sens ou est-ce que je manque quelque chose de facile? Si je suis sur la bonne voie, comment combiner un modèle de stratégie et un modèle de méthode de modèle?