An assignment in my software engineering class is to design an application which can play different forms a particular game. The game in question is Mancala, some of these games are called Wari or Kalah. These games differ in some aspects but for my question it's only important to know that the games could differ in the following:
- The way in which the result of a move is handled
- The way in which the end of the game is determined
- The way in which the winner is determined
The first thing that came to my mind to design this was to use the strategy pattern, I have a variation in algorithms (the actual rules of the game). The design could look like this:
I then thought to myself that in the game of Mancala and Wari the way the winner is determined is exactly the same and the code would be duplicated. I don't think this is by definition a violation of the 'one rule, one place' or DRY principle seeing as a change in rules for Mancala wouldn't automatically mean that rule should be changed in Wari as well. Nevertheless from the feedback I got from my professor I got the impression to find a different design.
I then came up with this:
Each game (Mancala, Wari, Kalah, ...) would just have attribute of the type of each rule's interface, i.e.
WinnerDeterminer and if there's a Mancala 2.0 version which is the same as Mancala 1.0 except for how the winner is determined it can just use the Mancala versions.
I think the implementation of these rules as a strategy pattern is certainly valid. But the real problem comes when I want to design it further.
In reading about the template method pattern I immediately thought it could be applied to this problem. The actions that are done when a user makes a move are always the same, and in the same order, namely:
- deposit stones in holes (this is the same for all games, so would be implemented in the template method itself)
- determine the result of the move
- determine if the game has finished because of the previous move
- if the game has finished, determine who has won
Those three last steps are all in my strategy pattern described above. I'm having a lot of trouble combining these two. One possible solution I found would be to abandon the strategy pattern and do the following:
I don't really see the design difference between the strategy pattern and this? But I am certain I need to use a template method (although I was just as sure about having to use a strategy pattern).
I also can't determine who would be responsible for creating the
TurnTemplate object, whereas with the strategy pattern I feel I have families of objects (the three rules) which I could easily create using an abstract factory pattern. I would then have a
WariRuleFactory, etc. and they would create the correct instances of the rules and hand me back a
Let's say that I use the strategy + abstract factory pattern and I have a
RuleSet object which has algorithms for the three rules in it. The only way I feel I can still use the template method pattern with this is to pass this
RuleSet object to my
TurnTemplate. The 'problem' that then surfaces is that I would never need my concrete implementations of the
TurnTemplate, these classes would become obsolete. In my protected methods in the
TurnTemplate I could just call
ruleSet.determineWinner(). As a consequence, the
TurnTemplate class would no longer be abstract but would have to become concrete, is it then still a template method pattern?
To summarize, am I thinking in the right way or am I missing something easy? If I'm on the right track, how do I combine a strategy pattern and a template method pattern?