ood case study (for parallel treatment, see chapter 2 of the text)
TRANSCRIPT
OOD Case Study
(For parallel treatment, see Chapter 2 of the text)
Elements of Class Design
Static class diagram UML: Unified Modeling Language
Pseudocode for operations Can be vague when it comes to details Should be precise about control and function
Criteria for Good Class Design
Correctness: solves the problem Simplicity Cohesion: everything in a class directed at a
single purpose Coupling/Information Hiding: classes should
never depend upon knowing the internal implementations of other classes
Error Handling: design should be robust.
Problem Statement: The 8-Puzzle
The 8-puzzle is a device consisting of eight numbered and sliding tiles arranged in a 3x3 grid. An 8-puzzle problem is an initial state and a final state along with a list of legal actions that can be performed on states.
2 8 31 6 47 5
1 2 38 47 6 5
2 8 31 47 6 5
2 8 31 6 47 5
2 8 31 6 4
7 5
2 8 31 6 47 5
up down left right
initial final
8-Puzzle Problem Statement (cont'd) You are to write a program that simulates the solving of an 8-
puzzle problem.
Your program must display an initial state of the 8-puzzle and then prompt the player for an action. After displaying the initial state, the program repeatedly prompts for actions, displaying the results of each action until the final state is achieved.
If an action is not possible, that is, it attempts to move a tile into an occupied space or off the edge of the board, the program must issue a diagnostic message and reprompt the player.
When the final state is reached, the number of actions made is displayed. Illegal attempted moves are not counted.
Important Aspects of the Problem Statement
It describes the problem and defines precisely what constitutes a solution
It makes clear the "rules of the game" It uses diagrams and examples It does not attempt to describe how the problem
is to be solved, only what the problem is It specifies the program behavior in sufficient
detail
Identifying Potential Classes:Collect Problem Statement Nouns
State
8-puzzle
Device
Board
Grid
Tile
Space
Action
Action List
Solver
Problem
Message
Player
Analyzing Potential Classes
State: holds all information about an 8-puzzle state including how to move tiles
8-puzzle, Device, Board, Grid: redundant
Tile: unnecessary
Space: part of a State
Action: contains a function for moving a tile
Action List: collection of Actions, one for each legal move
Problem: creates the Action List. Contains initial State, final State, and Action List
Solver: contains the Problem, knows how to prompt and check for solution
Message: unnecessary
Player: unnecessary
A Primitive Class Diagram
Problem
<Data>
<Operations>
State
<Data>
<Operations>
Action
<Data>
<Operations>
ActionList
<Data>
<Operations>
Solver
<Data>
<Operations>
Characterizing Classes Q: How do you determine which class to start
with? A: Identify classes that do not depend on others
for their definition: The Solver object requires a Problem to solve The Problem object requires an Initial State, Final
State, and ActionList The ActionList object requires Actions The Action object requires a State on which to
perform itself This leaves the State class as a good one with
which to begin.
Class Diagram with Dependencies
Solver<data>
<operations>
Problem<data>
<operations>
ActionList<data>
<operations>
State<data>
<operations>
Action<data>
<operations>
depends on
depends on
depends on
depends on
depends on
Elements of a Complete Class Diagram
All data specified with types All operations specified with return types,
parameters, and parameter types All operations specified as public or private (data
should never be public) Class dependencies indicated via annotated
connectors and arrows
Example: Solver Class
Solver
-problem: Problem
+Solver(p: Problem)+solve(): void-promptActionName(): String
Notes on the Solver Class
A ``-'' prefix indicates the data or operation is private, a ``+'' prefix indicates public.
The constructor for a class has the same name as the class.
The Solver constructor requires a Problem object from which to get the initial and final States, and the Action List.
The solve operation is public since it will be called from outside the class.
The promptActionName operation is private because it is used only by solve.
Another Example: The Problem Class
Problem
-startState: State-finalState: State-actionList: ActionList
+Problem(startTileNums: StringArray)+getStartState(): State+getFinalState(): State+getActionList(): ActionList-createActionList(): void
Notes on the Problem Class
The Problem constructor receives an array of strings from which to build the start State.
getStartState, getFinalState, and getActionList are data accessors used by the Solve class.
createActionList is a private operation that builds the ActionList by using the tile motion operations from the State class
Relationship of the Solver and Problem Classes
Solver
<Solver operations>
Problem
-startState: State-finalState: State-actionList: ActionList
<Problem operations>
problem1 1
Class Associations
The Solver and Problem classes are related by association, a relationship between instances of classes.
The label ``problem'' is the role name; the role that the Problem class plays for the Solver class.
When there is a role name, it can be left out of the box in the interests of simplicity.
The numbers at either end of the line are multiplicities; in this case there is always one solver and one problem
Pseudocode for the solve() Operationvoid solve()
current = get start state from problemfinal = get final state from problemalist = get action list from problemcount = 0while current is not final do
display currentaction = get action from userif action is valid then
new = apply action to currentcurrent = newincrement count
elseissue message
display current and countcongratulate
Notes on the Pseudocode
Nonexecutable Control structures used (while, if...then) Loop details not explicit Code blocks indicated through indentation
(personal preference)
State Class
Data:
Representation of the 8-puzzle board
Representation of the blank position
Operations:
Create a new state
Display the current configuration of the puzzle
Check if state is equal to another
Move blank up, down, left or right
. . .
New Class Diagram
Solver
<Solver operations>
Problem
-actionList: ActionList
<Problem operations>
Problem
1 1
State
<State data>
<State operations>
1
startStatefinalState2
Action Class
Data:
Name (up, down, left, right)
Operation to perform the action--What, an operation as data??
Operations:
Create a new action
Execute the action operation
. . .
Action Class Notes
Operations for moving the tile are already in the State class--why a separate Action class?
Because we want to abstract out as much of the generic design as possible for use with other problems
Abstraction is facilitated by having an ActionList composed of Actions.
To put an action on a list, it has to be regarded as data.
In C++, we will do this using pointers to static methods.
ActionList Class
Data:
The actions
The total number of actions
Operations:
Create a new action list
Add an action to the action list
Find an action by name
. . .
New Class Diagram
Solver
ActionList Action
Problem
State
problem
startStatefinalStateactionList
1 1
1
2
1 *
1
1
Comments on New Diagram
The relationship between ActionList and Action is one of aggregation, indicated by a diamond at the end of the line.
The multiplicity ``*'' means ``any number''.
The Art of OOD
There is no one correct design for a given problem.
You may wish to emphasize classes other than those chosen here.
You should design your solutions in a way which is natural to you.
However you should strive for SIMPLICITY.
Also, you should design for REUSE (difficult).
Advantages of Design Simplicity
Easier to understand Easier to implement Easier to debug Easier to maintain
Designing For Reuse
The general State class was chosen rather than the more specific 8-puzzle
The Action, ActionList, and Solver classes do not know anything about the 8-puzzle problem domain, so they can be applied to other domains
Advantage: Code can become part of a class library and used for other purposes
Example Class Definition in C++
class SolverInfo {private: Problem problem;public: SolverInfo(Problem p); void solve();private: static String promptActionName();};
Notes On the "SolverInfo" Class
1 Q: Why ``SolverInfo'' and not just ``Solver''? Because Solver will be defined to be a pointer to a class
object SolverInfo
2 No methods are defined in-line (defined in a separate file)
3 No data members are public
4 All public methods are part of the class interface
Example Main Program#include "ProblemInfo.H"#include "SolverInfo.H"
int main(Integer argc, StringArray problemArgs) {
Problem p = new ProblemInfo(problemArgs); Solver s = new SolverInfo(p); s->solve();}
Note that this program makes no mention of the 8-puzzle,and thus could be used on other problems suitably defined.