Cell Society Design Exercise
This exercise asks you to start the process of designing a program before you have written the code, i.e., before you have thought about exactly how it will be implemented. The key to this process is to think about high level behavior that you would like classes to implement, i.e., that would make it easier to do the project if they already existed, that is abstract as possible, i.e., that give you as much room to change your mind about the implementation when you have to actually implement each method.
The other important aspect of a project like this is to think about what abstractions, i.e., superclasses, in your project can have multiple concrete implementations, i.e., subclasses. If done well, most of your code will be written using the abstractions without needing to know about specific implementations because they are substitutable.
In your Cell Society teams, complete the following activities today:
- Review a Game project to find ways to use inheritance to improve the code
- Create a high level design for Cell Society
- Use CRC cards to refine your plan, focusing more on the interactions between components than their implementation
- Write code to solve some example Use Cases
Use Gitlab's markdown format to record the
team's discussion in a file called doc/DESIGN_EXERCISE.md
within your team's Cell Society repository. Here is a web-based WYSIWYG editor for markdown if you prefer.
Inheritance Review
Examine one person's Game project (preferably that did not use inheritance) and focus on how making an inheritance hierarchy from the following kinds of classes would improve the overall code:
- bricks
- power ups
- levels
- others?
For each set of objects, write the method signatures (i.e., not the implementation) the superclass would need to have to support all possible subclasses in the game and a comment describing what each method's purpose is. This defines the abstraction that represents all of those concrete examples and what other classes the abstraction must absolutely be dependent on.
Cell Society High Level Design
Consider the following questions as you discuss the basic design elements of the Cell Society project. Write a high-level description of the different parts of the project and how they can interact without worrying about the implementation details.
- How does a Cell know what rules to apply for its simulation?
- How does a Cell know about its neighbors? How can it update itself without effecting its neighbors update?
- What is the grid? Does it have any behaviors? Who needs to know about it?
- What information about a simulation needs to be the configuration file?
- How is the GUI updated after all the cells have been updated?
A picture may be helpful to show how your parts are related to and dependent on each other.
Class-Responsibility-Collaborator Cards
Now that your team has thought about the problem generally, 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.
- What actions is this class responsible for?
- What other classes are required to help this class fulfill those responsibilities?
These other classes will either be passed to this object's constructor or methods, or returned from a method, or created by this object internally.
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 signature to provide more details about the flow of the program.
When designing classes, 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).
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.
- Apply the rules to a middle cell: set the next state of a cell to dead by counting its number of neighbors using the Game of Life rules for a cell in the middle (i.e., with all its neighbors)
- Apply the rules to an edge cell: set the next state of a cell to live by counting its number of neighbors using the Game of Life rules for a cell on the edge (i.e., with some of its neighbors missing)
- Move to the next generation: update all cells in a simulation from their current state to their next state and display the result graphically
- Set a simulation parameter: set the value of a parameter, probCatch, for a simulation, Fire, based on the value given in an XML fire
- Switch simulations: use the GUI to change the current simulation from Game of Life to Wator
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 Java method calls to provide more details about the flow of the program.
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 design.
Submission
Push your markdown file, doc/DESIGN_EXERCISE.md
, to your team's Gitlab repository by the end of class. Make sure the document includes everyone's name that worked on it.