CompSci 308
Spring 2024
Advanced Software Design and Implementation

Lab Coding Exercise: Refactoring Code into Multiple Classes

In this lab, you will refactor a working game of Hangman to remove code duplication. Refactoring is the process of changing the implementation of a piece of code without changing the functionality. The result of this lab will be a Hangman game that functions the same as the initial game, but has less duplication and is easier to read and update.

The lab has the following steps:

  1. Setup Pair Programming Environment
  2. Read the Original Code
  3. Plan your Refactoring
  4. Refactor
  5. Debrief
  6. Submit Your Work

Please complete each step before moving onto the next.

Setup Pair Programming Environment

Labs in this course expect you to work either in pairs or with your project team.

Professionally, this practice is called Pair Programming. When Pair Programming, you will:

Follow these steps to setup your Pair Programming environment:

  1. Choose a Partner’s Computer to Work On: Both partners will code using the same computer, called the Driver Station. (If you are uncomfortable with sharing a computer, see Simulating Pair Programming Across Machines for alternative setups. However, please note these will make the lab more complicated and make it take longer).
  2. Fork Project on Gitlab: One partner should fork the original project lab_hangman to their repository to allow pushing your pair's changes.
    • On the resulting project web page, go to Project Information → Members (in the upper left corner) to add your partner so both people in the group can access the same repository
    • Search for your partner's name and give them a Maintainer role in the project and choose Add to Project
  3. Clone Repository in Terminal: On the Driver Station, git clone to copy the forked repository to the local machine.
  4. Open Project in IntelliJ: On the Driver Station, open the cloned folder in IntelliJ to start a new project.
  5. Update DISCUSSION.md: In IntelliJ, add group members’ names and NetIDs at the top of DISCUSSION.md.
  6. Add, Commit, and Push DISCUSSION.md: This will ensure your whole lab setup is functioning end-to-end.

Note: When pair programming, it is a good idea for the non-coding partner to have a copy of the code in front of them for reference. This will also help in the next section.

Before Moving On: Add your names to the DISCUSSION.md file, then add, commit the file, and push to your forked lab_hangman repository..

Read the Original Code

Background

In the game of Hangman, one player tries to guess a secret word that another player has chosen by guessing a letter at a time. To simulate this in lab, there are two similar versions of the game that include four different kinds of players (based on assignments given in CompSci 101). A player is either a guesser or secret keeper.

Discussion

In this section, you will read over the two classes above and discuss it with your partner. Then, you add short summaries of your discussion to the Original Code section of DISCUSSION.md file.

Note: you only need to consider the code in the game package, not the util package.

Overview

To guide your discussion, consider the following questions:

Adding new Functionality

To help identify candidate code within each game that could be turned into methods to represent a player's behavior, describe how would you make the following new game using the current design:

For this discussion, do not worry about the exact Java code needed to implement these players, just identifying what lines in either one of the game classes needs to be changed to implement two new players described above.

To guide your discussion, consider what parts of the code do the two game classes have in common and what parts are different (note, use can use Window → Editor Tabs → Split Right to view the two classes side by side):

Before Moving On: Write short summaries of your discussion in the DISCUSSION.md file, then add, commit the file, and push to your forked lab_hangman repository.

Plan Your Refactoring

Refactoring is the practice of updating a program to improve its design and maintainability without changing its current functionality. For example, creating a single method from two similar code blocks to reduce duplicate code.

In this section, you will plan several refactoring steps to change two classes with heavily duplicated code with no clear intentionality into the following classes:

The main objective of this refactoring is to ensure these classes have no duplicated code. You will also separate the game rules from the player logic so that they can be changed independently.

Update the Refactoring Plan section of the DISCUSSION.md file. Write down the methods you will create for each of the three classes, HangmanGame, Guesser, and SecretKeeper. For each method, specify

You can do this using standard Java syntax followed by a comment. For instance,

public String sayHello(String name)
// creates a greeting in the format "Hello, {name}"

The goal of this step is not to get all the implementation details exactly correct, but rather to develop an understanding of how the classes need to interact with each other to remove duplication.

To help you in this process, consider the following:

Your pair may create any new methods or classes you want to help improve the program. However, because the functionality of the program should not change in this refactoring, you should focus primarily on moving existing code rather than creating any new code.

Before Moving On: Write short summaries of your discussion in the DISCUSSION.md file, then add, commit the file, and push to your forked lab_hangman repository.

Refactor

Using pair programming in 15 minute increments (or after each change described below), perform the refactoring your planned above.

First, rename InteractiveHangmanGame to HangmanGame. For the rest of your refactoring, you will gradually extract functionality out of HangmanGame into Guesser and SecretKeeper classes. Below, an ordering of steps is provided, but not the changes themselves. You will need to implement the methods you defined your Refactoring Plan. It’s fine if you need to alter the methods from what you originally planned to make things work.

Note: Please leave at least 20 minutes at the end of lab to Debrief and Submit your Work. It is okay if you are not finished with your refactoring by then. Just find a stopping place (ideally with working code), commit your changes, and move on to Debrief.

Interactive Guesser

Make sure you can play an interactive game using your new Guesser.

Add and commit your changes to the source code before moving on.

Random SecretKeeper

Make sure you can play an interactive game using both the Guesser and your new SecretKeeper.

Add and commit your changes to the source code before moving on.

Auto Guesser

No changes should need to be made to the HangmanGame or Main classes. For now, just comment out the interactive implementation. We will see a better way to handle this next week.

Make sure you can run an auto game using both the Guesser and your new SecretKeeper.

Add and commit your changes to the source code before moving on.

Sneaky SecretKeeper

No changes should need to be made to the HangmanGame or Main classes. For now, just comment out the random implementation. We will see a better way to handle this next week.

Make sure you can run an auto game using both the Guesser and the sneaky version of the SecretKeeper.

Before Moving On: Add and commit your changes to the source code and push them to your forked lab_hangman repository.

Debrief

In this section, review your changes (or planned changes if you did not get to implement everything). Then, you add short summaries of your discussion to the Debrief section of DISCUSSION.md file.

Extending Functionality

Discuss with your partner, as concretely as you can, how to implement these changes using this new version of the code:

Reflection

Taking the totality of the lab in mind, discuss the following with your partner:

Submitting Your Work

At the end of lab, use Gitlab's Merge Request from your forked repository's main branch back to the original organization repository's main branch to submit your group's answers to the discussion questions and your refactored code.

Make the Title of your Merge Request is of the form "lab_hangman - everyone's NetIDs".

You only need to create one Merge Request, no matter how many commits you make, and you do not worry about potential conflicts since your request will not be approved (it is just an easy way for us to see what changes you made).

Appendix

Simulating Pair Programming Across Machines

If you are using two machines for Pair Programming, then both lab partners need to clone the environment (as instructed above).

You have two options for synchronizing across machines: