I've put together two separate programs which play a card game called 'Crazy Eights'.
The classes I've written for this program are based on a default 'card' package which provides playing card objects and some generic methods for playing cards.
I've taken two separate approaches to achieve this which are both functional in their own right.
Here are two UML class diagrams which depict the two approaches:
Inherited subclass 'conversion' method
Composed subclass with similar methods
As you can see in approach 1 the class EightsCard contains a method convert(Card) Here's the method:
/**
* Converts a Card into an EightsCard
* @param card The card to be converted
* @return The converted EightsCard
*/
public EightsCard convert(Card card) {
if (card != null) {
EightsCard result = new EightsCard(card.getRank(), card.getSuit());
return result;
}
return null;
}
}
This method allows you to call methods from CardCollection which otherwise wouldn't be legal. For example, in the play method from the EightsPlayer class shown below:
/**
* Removes and returns a legal card from the player's hand.
*/
public EightsCard play(Eights eights, EightsCard prev) {
EightsCard ecard = new EightsCard(0, 0);
ecard = ecard.convert(searchForMatch(prev));
if (ecard == null) {
ecard = drawForMatch(eights, prev);
return ecard;
}
return ecard;
}
Approach 2 doesn't require any conversions as the similar methods have been written in a new class EightsCardCollection which extends CardCollection. Now the play methods can be written like this:
public EightsCard play(Eights eights, EightsCard prev) {
EightsCard card = searchForMatch(prev);
if (card == null) {
card = drawForMatch(eights, prev);
}
return card;
}
This brings me to a couple of questions:
- Are there any advantages to either approach beyond personal preference?
- Is there a better way to compose this program?
For example, might it be better to write 'similar' classes which are more specific1 and not use default classes2 at all.
1 labelled 'crazyeights.syd.jjj' or 'chaptwelvetofort' in the class diagrams.
2 labelled 'defaults.syd.jjj' or cards.syd.jjj' in the class diagrams.