Issue: An Award Criteria has information about what criteria a bowler and scores must meet to be eligible for an award. These are such things as age (senior awards), whether the award has already been won, (once per season awards), the bowler's average (average based awards), and the score. The actual computation of the award varies depending upon the type of the award. For example, a game award is based on a single game score and the bowlers average, while a series award is based on the series score and the bowler's average. However a triplicate award is based soley on the three game scores, regardless of the bowler's average. There are also pins over average awards for games and series. So the issue is how to implement the computation of awards?
Discussion: To do the computation there are at least two ways to handle this. One is to use an Enum, another is to create separate classes for each award type. In each case either an abstract method or an interface is needed so that a method is called returning a list of awards (there can be more than one for any game or series) or an empty list if no award is earned.
The Enum version would fit into the Tic object structure as it currently exists, while the separate classes version would require changes to the Tic supporting methods for object creation. This refers to the ability to create objects from a text file. The text would be the class name, and the objects created from that name using reflection. However, when the user is selecting which award type, to create a AwardCriteria object, the local name must be used. This could come from a ResourceBundle, possibly.
Both versions are or can be serializable. Both versions are (Enum), or can be (separate classes) statically accessed.
If a new award type is needed, the actions needed are different. The Enum version would require adding a new enum value and defining the method for it which does the computation. The separate classes version would require creating the new class with the required method definition. The separate classes version would also require changes to the Tic supporting methods for creating new objects. No changes to the Tic methods are needed for the Enum version. The separate classes version would also require some way to convert the local name into the correct class name to be stored in the text file. This also means the text file is no longer in the local format.
I've decided that the best way to get the awards earned is to have the computation method return a java.util.List object with one or more AwardEarned objects in the list. Obviously, a list with no size, that is empty, means no awards were won from those scores. The computation method will need a lot of information to determine if an award is won. Specifically, this is the actual Series object, which contains the Games objects, the Member object for the bowler who achieved the scores. The Series object will also contain the Contest object representing the contest date as well as the actual date that the scores were achieved. This is all information which must be included into the AwardEarned object.
Conclusion: While both versions have their advantages and weaknesses, I have decided that the Enum version requires the least amount of changes to code if a new award type is needed. Enum can already be stored in text files using the local names, and correctly converted from the local text into object instances, with out changes to the Tic supporting classes.
The currently known award types are:
- Game score, average based. Includes 300 game.
- Series score, average based
- Triplicate, all games with the same score
- Eleven strikes in a row
- Pins over average for game
- Pins over average for series