CompSci 307 Fall 2022 |
Software Design and Implementation |
This exercise is intended for you to start designing a program without worrying about how it will be implemented. Planning is essential when programming as a team to help clarifies people's responsibilities and avoid unnecessary GIT conflicts. Thus, without implementing any functionality, determine a set of objects that you think represent elements in the problem and can work together to implement a solution.
There will not be an official submission for this exercise, instead show your progress to a UTA during lab when you think you are finished to get feedback.
In your team, complete the following activities:
Note, while these examples show typical examples of CRC Cards and Use Cases, as novices write yours as a close to Java as possible to make sure you include enough details for us to verify your design makes sense.
Consider designing a software version of the eternal game of Rock, Paper, Scissors, RPS, that can support any number of choices 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.
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.
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.
A picture may be helpful to use UML to show how your classes are related to and dependent on each other (even in Markdown!).
One of the strengths of object-oriented design is creating program objects that model corresponding objects from the real world when designing classes. The best way to design an effective class is to "anthropomorphize" the real world object, i.e., give it human characteristics and responsibilities, because it gives the class agency through active behaviors and thus a more defined role in the design. This distinguishes a good object-oriented design (a group of collaborating objects) from a bad one (a group of passive objects coordinated by a "manager" object).
Thus, when designing smart objects, focus first on each class's behavior (the methods a class implements) rather than its state (instance variables). Then for each behavior that fits with a class, give it a clear purpose by thinking about how much easier it would make the project if such a method already existed (even if you are not currently sure how to implement it). But balance that with making the behavior general enough that a coder can change their mind about the implementation when they have to write it.
After thinking about a problem generally, many people find CRC Cards useful to describe a Object-Oriented design because they help make the objects more concrete, the logical relationship between objects explicit, it is easier to understand, evaluate, and modify a design. A CRC Card is an index card (which nicely limits how much a class can do and are easy to change and move around to see their relationship visually) that helps you focus on making active objects by answering the following questions for each class:
Here is an example of developing complete CRC Cards. However, in this examples, the responsibilities are given in simple English, not as a Java method signature (name, parameters, and return type). Your version must be written as a Java method signature to help provide more details about the flow of the program.
To create your CRC Card design, you can either:
The following scenarios are provided to help test the completeness 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 (even in Markdown!). For this exercise, try to include both the class used and the method used to accomplish the step.
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.
To complete your Use Cases, you can either:
To make things more interesting, pair up with another team and try to do this part using their CRC cards.