Assignment 7: Refactoring for Extensibility, Maintenance, and Readability
Objective: This assignment is intended to get you to practice some of the programming and design techniques discussed in class, including
- understanding another's code design
- refactoring the current code--for readability, maintainability, and extensibility
- testing the refactored code to verify that it still works
- adding functionality to the refactored code
Due: before class by 11:59 p.m. on Thursday, November 11 with recommended completion by Wednesday, November 10.
Set Up
- Accept the assignment and copy the clone link.
- Within Eclipse, in the "Git Repositories" view, clone the repository.
- In the Git Repositories view, expand the repository
- Right-click on the Working Tree and select "Import Project". No changes should be required in the dialog.
- You should now see a new project in the Package Explorer view.
- Update your classpath:
- Right-click the project, select Build Path -> Configure Build Path
- In the Libraries tab, click on Classpath, and then click on "Add Library...". Select "JUnit", click Next, and then choose JUnit 5 from the dropdown, and click "Finish".
If you see no red X's on the project, you should be good to go.
Understanding the Design
Execute the code. What is the driver for this project?
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 new kinds of bets and how closed it is to modification. To help direct your analysis, consider the following questions:
- What are each class's responsibilities?
- How many other classes know about the
Bet
class? - What code would 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)?
Note: There is one bug in the code: determining if Odd/Even Bet was won is incorrect.
Refactoring
Examine the code given and refactor it according to the Open-Closed Principle as well as the other design principles we have studied. You may create any new classes you want to solve this problem.
To help direct your refactoring, consider the following questions:
- What methods would make sense as behaviors of a Bet hierarchy (i.e., make bets open to extension)?
- What methods would help improve the code in the Game's methods (i.e., close it to modification)?
- What methods can be completely implemented in
the
Bet
class (i.e., are constant across the hierarchy), and which completely in theBet
child classes (i.e., must be specialized across the hierarchy)? - How should the Game class create the correct Bet child objects, and thus leverage the Bet child classes' functionality?
You are most focused on extensibility but also look for other code smells or issues with readability/maintainability in the code.
Testing
You should provide a set of automated unit tests that verify your modified program still works as intended. Focus your automated tests on the code that does not relate to user interaction. (Why?)
To help direct your unit testing, consider the following questions:
- How can you test a program that is primarily based on randomness?
- Could you easily remove the randomness?
- Could you make it easy to turn randomness on and off?
- Could you make it easy to test several different kinds of bets?
In addition, you should be systematically testing your code in other ways to ensure that every line of code works as intended.
Improving
Add the three bets given in the original specification not implemented in the code given to you, adding as little new code as possible.
Create test cases to ensure all of the bets work. Run the test cases with coverage to see how much you covered.
Analysis of Code
In the README.md file, compare the effort to create a new bet in your improved code to how you would have done it in the original code. To focus your answer, consider the following questions:
- 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 the old code?
- Which code do you prefer and why?
Additionally, discuss
- the testing challenges of this project and how you addressed those challenges
- how you systematically tested your code, beyond unit testing
Hints/ Suggestions/ FAQ
- I can't figure out the bug in the Odd/Even Bet. Can I have a hint?
- Check out the roulette specification (linked above) to make sure you understand the rules.
- I can't figure out how to do X.
- See if there is similar code elsewhere in the project code base or in one of our previous assignments.
- Use git and commits to help you keep track of your changes and help you roll back changes.
- Use your tools!
- Ack! My refactoring blew things up!
- That will happen. This is good practice for you! The question is, should you keep moving ahead, or should you roll back to your previous version (see above)? Push ahead for at least a little bit--don't be too quick to roll back. Think about "what will make this work?" If the answer is "pass in a parameter", that sounds good. If it's "make this instance variable public", that's probably not the right choice (it violates shy code principle). This is definitely a tricky call. Part of the goal of this assignment is to give you experience with refactoring to help you gain good judgement.
- I found a bunch of code smells in this one part of the code. Should I address all of them?
- Consider which is the smelliest code smell. Which is the worst offender? Often, if you address the "worst" code smell, you'll address the others. If not, repeat searching for code smells and addressing them.
- I'm overwhelmed. Help!
- Take a deep breath and clear your head. You can do this. You are bringing together ideas from throughout the class. You are confirming your Java programming knowledge. Focus on the Game/Bet class interaction. If you're stuck, break into smaller pieces, write comments that tell you what you need to do, break those pieces/comments into smaller pieces, ... You can also talk to/email me. Sometimes, just writing an email helps to clarify your thoughts.
Submission
I will grade everything that is in the main
branch in
your GitHub repository that is shared with me.
Grading (200)
Your grade will be based on
- refactoring (75): how well you addressed code smells and made the code easier to extend, read, and maintain
- README.md (30): how well you justified how you refactored the code and explained the tradeoffs between the approaches; discussion of testing
- implementation of 3 new bets (40): correctness, style
- testing (40): how well you tested and verified that your solution works
- general style, code documentation (Javadocs) (15)