Code Critique and Refactoring
This exercise is intended to help you to learn to critically read code, understand its purpose, and identify ways to improve its design. Along the way, you should start to build a sense of the reader's expectations about code and what makes one piece of code better than another given a specific set of design goals. In pairs, examine the code from the perspective of how readable and extensible it is. While studying this code, also note any good things about the code, that you might keep in the final version as well as smells in the code.
CompSci 101 currently, and CompSci 201 previously, give an assignment based on the game of Hangman. It is typically given in multiple parts based on what concept students are learning in the course, but the instructions tend to be the same: copy your previous version and update it to implement a new kind of player or a new kind of executioner. To simulate this, there are three versions of the game that each play slightly differently. Your goal in the exercise is to separate the game logic from the player logic so that they can be changed independently.
To work on this lab exercise, fork the original project lab_hangman into your own repository so you can edit, commit, and push your group's own changes.
Discussion
In pairs, read over the code to see if you have any questions about how it works. Then spend some time evaluating the code from a design perspective using the following questions as a guide:
- What pieces of code help versus obscure your understanding?
- What comments might be helpful within the code?
- Are there places where the code could be more concise and also more clear?
- What additional methods or classes might be helpful?
- What Code Smells can you find?
- What dependencies are there between different parts of the code?
- How easy is it to identify those dependencies as part of the game or player logic?
- Can you clarify or remove those dependencies by creating different classes and encapsulating some logic?
- What suggestions does this new code make about how someone would extend it in the future to add different playing algorithms?
Use Gitlab's markdown format to record the group's answers in the file called DISCUSSION.md that is included with the example code. IntelliJ includes a markdown editor that provides a preview or here is a web-based editor that provides similar functionality and can be shared like Google Docs.
Refactoring
Refactoring is the practice of updating a program to improve its design and maintainability without changing its current functionality significantly. An example of refactoring is creating a single method or class that replaces two or more sections of similar code because it reduces the amount of redundant code within the program and makes the code easier to debug and test.
Examine the given program and refactor it based on your group's discussion. Your group may create (and comment why you choose to create them) any new methods or classes you want to help improve the program. Try to justify each change you make by explaining specifically how it improves the code. Justifications should refer specifically to principles discussed in class or the reading rather than using terms like "clearly/obviously", "good/sucks", or "like/hate".
After you have done as much as you think is reasonable, 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 original code?
- Which code do you prefer and why?
Version Control Workflow
Here is a review of the steps you will use to work with GIT during labs (as distinct from assigned team projects):
- On Gitlab, fork the original project
lab_hangmaninto your own repository so you can edit, commit, and push your group's own changes - In Terminal, use
git cloneto copy the code from your forked SSH location - In IntelliJ, create a Java project in the same folder you cloned the project to
- As a group, discuss the design issues above
- In IntelliJ, refactor the code to improve its design (i.e., edit the code)
- In Terminal, use GIT to
git addchanged filesgit commit -mto describe your changesgit pushchanges back to Gitlab- Repeat as many times as needed, letting each person try the changes/GIT steps in related chunks
- On Gitlab, when you are done, use Gitlab's Merge Request from your forked repository to the original. Do not worry about potential merge conflicts, your request will not be approved.
Submission
At the end of class, use Gitlab's Merge Request to submit your group's answers to the discussion questions above and refactored code to the original organization repository. Make sure the NetIDs of everyone in the group are in the title of your Merge Request and in the markdown file.