CompSci 308
Spring 2023
Advanced Software Design and Implementation

RPS Design Exercise

One of the strengths of object-oriented design is creating objects model corresponding objects from the real world. However the best way to make an effective class is to "anthropomorphizing" it, i.e., to give it human characteristics and responsibilities — this is often what helps to distinguish a good object-oriented design (a group of intelligent objects collaborating together) from a bad one (a group of passive objects coordinated by a manager object). Focus on the behavior (methods) that you would like the classes to implement, i.e., that would make it easier to do the project if they already existed, rather than the state (instance variables) and try to make each behavior as general as possible, i.e., give coders as much room to change their mind about the implementation when they have to actually writing each method. Specifically, it should be possible for your design to avoid requiring any specific data structure or file format.

Complete the following activities to create your design:

  1. Discuss high level design ideas for the RPS problem, without worrying about how your classes will get their input (either from the user or from configuration file formats)
  2. Use CRC cards to refine your design, focusing more on the interactions between classes than their implementation
  3. Write "example code" to solve some example Use Cases to test your design's completeness against some specific scenarios

Note, while these examples show typical examples of CRC cards and Use Cases, in this exercise you are expected to write yours as a close to Java as possible to make sure you include enough details to verify your design makes sense.

Specification

Consider designing a software version of the eternal game of Rock, Paper, Scissors, RPS, that can support any number of choices (or this one) and their relationships as well as allow users to create new variations. Since there are RPS Championship Tournaments, it appears that there is a strategy (beyond simply cheating or understanding psychology), if time permits you can consider how to represent "RPS intelligence" as well. This podcast episode discusses this classic game in great detail.

Write a high-level description of the classes you envision as part of implementing RPS, focusing on their behavior. High-level means explaining each class's purpose in the program (why it exists) without describing its implementation details. A class's behavior is its public methods, including any parameters and a return value. These method signatures should be written as they would appear in Java code, but your focus should be on describing their purpose in the class, not their implementation.

You can assume a user interface will be provided for you that allows the user to choose a file containing data about the "weapons" available for a game and displays the results of each round of the game. Your program should accommodate reading from a data file and populating a data structure but, as much as possible, try to encapsulate both the file's format and the specific data structure so as few classes as possible need to know about it (if you even need to choose a specific one at all). The best way to do this is actually to try envisioning two different implementations (i.e., data structures and file formats) and then design your method signatures so they do not reveal the specifics of either implementation option.

A picture may be helpful to use UML to show how your classes are related to and dependent on each other.

Class-Responsibility-Collaborator Cards

Now that your group has thought about the problem generally, you will use CRC cards to refine your design and help you focus on interface instead of implementation issues. A CRC card is an index card (which nicely limits how much each class can do) that answers the following questions about a class to describe its behavior without getting into the details of how it implements that behavior. Index cards are also useful because they are easy to change and move around to see their relationship visually.

Here are some examples of completed CRC cards. In these examples, the actions are given in English, not as a Java method signature (name, parameters, and return type). Your version must be written as a Java method signature to provide more details about the flow of the program.

Use Cases

The following scenarios are provided to help test the completeness and flexibility of your design. By writing the steps needed to complete each case below you will be able to see how effectively your design handles these scenarios and others will be able to better understand how deeply you have considered the basic issues. It may help to role play or draw a diagram of how your classes collaborate to complete each case. For this exercise each step, try to include both the class used and the method used to accomplish the step. To make things more interesting, pair up with another team and try to do this part using their CRC cards.

Here are some examples of completed Use Cases. In these examples, the steps are given in English, not as a Java method calls. Your version should be written as a sequence of calls to only those Java methods on your CRC cards to provide more details about the flow of the program.