Roulette: Refactoring Code for Extensibility
This project is intended to get you to practice some of the programming and design techniques discussed in class recently and consists of four activities:
- understand the current code
- refactor the current code
- test the refactored code to verify that it still works
- add additional functionality to the refactored code
Understanding the Design
There are many different ways to bet on the results of spinning a roulette wheel. The current program only supports three such ways; however, the next version of the program should support three additional ways to bet on the results. Analyze the design of the current program from the perspective of how open it is to adding addition kinds of bets and how closed it is to modifcation.
To help direct your analysis, consider the following questions:
- How many other classes know about the Bet class?
- What code would be need to be added to game to allow the user to make another kind of bet that paid one to one odds and was based on whether the number spun was high, between 19 and 36, or low, between 1 and 18?
Refactoring
You should examine the code given and refactor it to use an inheritance hierarchy of bets such that your refactored code minimizes the amount of new code required to add another type of bet. You may create any new classes you want to solve this problem.
To help direct your refactoring, consider the following questions:
- What functions would make sense as behaviors of a Bet hierarchy (i.e., make bets open to extension)?
- What functions would help improve the code in the Game's methods (i.e., close it to modification)?
- What functions can be completely implemented in the Bet super-class (i.e., are constant across the hierarchy), and which completely in the Bet sub-classes (i.e., must be specialized across the hierarchy)?
- How should the Game class create the correct Bet sub-class?
Testing
You should provide a set of tests that verify your modified program still works as intended. Tests can be in the form of input data files, driver programs, or other classes that verify every line of code written works as intended.
To help direct your testing, consider the following questions:
- How can you test a program that is primarily based on randomness?
- How can you easily remove the randomness?
- Can you make it easy to turn randomness on and off?
- Can you make it easy to test several different kinds of bets?
- How should you package your testing code so that it is easy to run repeatedly?
Improving
Finally, using your improved code, you should add the three bets given in the original specification not implemented code given to you, adding as little new code as possible.
Compare the effort to create a new bet in your improved code to how you would have done it in the original code.
- In what ways is the refactored code simpler?
- In what ways is the refactored code more complex?
- What trade-offs did you make when refactoring your old code?
- Which code do you prefer and why?