|
|
|
Putting together a complete system |
|
|
|
|
Designing a complete system. |
|
Overview of the design and implementation
process. |
|
Example of a simple game called “nim.” |
|
|
|
|
|
problem analysis: a thorough examination of the
problem to be solved. |
|
functional
specifications: a precise description of what the system is intended to do. |
|
A contract between the user and the developer. |
|
|
|
|
design phase: defining a collection of classes
and their interactions to satisfy the specifications. |
|
implementation: constructing the software
modules that make up the system. |
|
testing: ensuring that the modules conform to
the specifications. |
|
|
|
|
|
|
|
Iterative and incremental |
|
Inadequacies often are found. |
|
Testing uncovers design and implementation
flaws. |
|
Test plans must be updated continually as the
process proceeds. |
|
Compositional |
|
The system is composed of simpler pieces
(objects, algorithms). |
|
Evolving |
|
The problem a system is designed to solve
inevitably changes over time, requiring system maintenance. |
|
|
|
|
|
A typical system consists of three fundamental
subsystems: |
|
Interface |
|
Model |
|
Data management |
|
|
|
|
|
|
|
A system must communicate with the external
world. |
|
It is generally desirable to isolate these
functions into a collection of objects called the external interface or user
interface. |
|
It obtains and verifies input. |
|
It formats and presents output. |
|
|
|
|
|
Many systems must manage some external data. |
|
Example: a bank must keep customer account and
transaction records even when the bank is closed. |
|
persistent data: data maintained externally and
independently of what the system is doing, and which continues to exists. |
|
The part of the system responsible for storing
and retrieving persistent data is the data management subsystem. |
|
|
|
|
The components that actually solve particular
problems. |
|
|
|
|
|
|
Student registration example |
|
|
|
|
Two players and a pile of sticks. |
|
Each player in turn removes 1, 2, or 3 sticks
from the pile. |
|
The player who removes the last stick loses. |
|
|
|
|
|
Play a number of games of “simple nim,”
reporting the results to the user. |
|
Allow the user to specify the number of sticks
the pile contains at the start of the game. |
|
For each player in turn, determine the number of
sticks to remove and make the play. |
|
Display the state of the game after each play. |
|
Allow the user to determine whether another game
is to be played. |
|
|
|
|
There are many possible approaches and rarely
one “best” solution for any non-trivial problem. |
|
The task of the designer is to explore the
“solution space” for the problem, and evaluate alternatives. |
|
With our implementation, we will aim for
simplicity. |
|
|
|
|
User interface - how the user interacts with the
system. |
|
Model to play the game. |
|
No data management is required. |
|
|
|
|
|
|
|
Design involves defining a collection of objects
and their interactions to satisfy the specifications. |
|
Specify classes |
|
some derived from the external system. |
|
“architectural” classes that form the underlying
structure of the solution. |
|
“implementation” classes to support the
algorithmic implementation of the system. |
|
|
|
|
An initial collection of potential
problem-modeling classes can be developed by carefully examining the
required system functionality. |
|
Other potential classes, architectural classes,
and organizational approaches will suggest themselves as responsibilities
are allocated to these classes and relationships between them are
identified. |
|
|
|
|
|
|
In the “nim” example, we will use a Player class
(2 player objects), and a PileOfSticks class. The sticks individually don’t have much meaning. |
|
We will also include a GameManager class that
will keep track of things such as whose turn it is. |
|
|
|
|
|
Pile: |
|
Know how many sticks remain |
|
Remove sticks. |
|
Player: |
|
Know its name. |
|
Remove a certain number of sticks. |
|
Know how many sticks it took on its last turn. |
|
|
|
|
|
GameManager: |
|
Know Players and Pile. |
|
Know whose turn it is. |
|
Know when the game is over. |
|
Know who the winner is. |
|
Know how many stick can be taken per turn. |
|
|
|
|
The Pile is a complete server-- it requires no
other objects to satisfy its responsibilities. |
|
The Player needs the Pile in order to move. |
|
|
|
|
|
|
|
|
The user interface is a mechanism for viewing
and controlling the solution process. |
|
It generally is preferable for the model to be
as independent of the user interface as possible. |
|
The interface is usually one of the least stable
parts of the system, and often among the last to be finalized in system
design. |
|
We will design our user interface as a client of
the model. The user interface
queries the model for information and commands as directed by the user. |
|
|
|
|
The system responds to “events” that occur
external to the system; in our case they will be user actions. |
|
|
|
|
|
|
|
The user interface must know when the model
changes states. |
|
The observer tells the target, “I need to know
when you change state.” |
|
Whenever the target changes state, it informs
the observer “I’ve changed state.” |
|
The observer then queries the target for any
detailed information it needs. |
|
|
|
|
To implement the relation, the target provides a
method (register) for the observer to use to identify itself to the target,
and the observer has a method (update) that the target calls to inform the
observer of a state change. |
|
|
|
|
|
Client invokes Target.change; |
|
Target invokes Observer.update; |
|
Observer.update; |
|
Target.queryState completes and returns
control to Observer; |
|
Observer.update completes and returns
control to Target; |
|
Target.change completes and returns control to
Client. |
|
|
|
|
|
|
public Pile (int number) |
|
Create a
Pile with the specified number of sticks. |
|
require:number
>=0 |
|
ensure:this.size()
== number |
|
|
|
public Pile () |
|
Create
an empty Pile. |
|
ensure:this.size()
== 0 |
|
|
|
public int size () |
|
Number
of sticks in this Pile |
|
ensure:this.size()
>= 0 |
|
|
|
|
|
|
public void setSize (int number) |
|
Set the
number of sticks in this Pile |
|
require:number
>= 0 |
|
ensure:this.size()
== number |
|
|
|
public void remove (int number) |
|
Remove
the specified number of sticks from this Pile. If the specified number is more than the Pile size, remove
all the sticks. |
|
require:
number >=0 |
|
ensure: this.size()
== max (0, old.size()- |
|
number) |
|
|
|
|
public Player (String name) |
|
Create a
new Player with the specified name. |
|
require:name
!= null |
|
ensure:this.name()
== name |
|
|
|
public String name () |
|
This Player’s
name. |
|
|
|
|
public void setName (String name) |
|
Change
this Player’s name. |
|
require:name
!= null |
|
ensure:this.name()
== name |
|
|
|
public int numberTaken () |
|
Number
of sticks taken on this Player’s most recent turn. |
|
ensure:4
> this.numberTaken() >= 0 |
|
if Player has not yet had a turn, this.numberTaken
== 0 |
|
|
|
|
public void makeMove (Pile pile, int maximum) |
|
Make a
move: remove up to specified maximum number of sticks from the specified Pile. |
|
require:pile
!= null |
|
4 > maximum > 0 |
|
|
|
|
public GameManager (Player player1,
Player player2) |
|
Create a
nim GameManager, with the specified players; by default, the first Player specified
plays first in the first game. |
|
require: |
|
player1 != null |
|
player2 != null |
|
|
|
public int sticksLeft () |
|
The
number of sticks in the Pile. |
|
ensure:this.sticksLeft()
>= 0 |
|
|
|
|
|
|
|
|
public int sticksTaken () |
|
The
number of sticks taken on the last play. |
|
ensure:this.sticksTaken()
>= 0 |
|
|
|
public Player nextPlayer () |
|
The Player
whose turn is next. |
|
|
|
public Player previousPlayer () |
|
The Player
who last played; returns null if no play has been made yet. |
|
|
|
|
|
|
|
|
public boolean gameOver() |
|
The game
is over. |
|
|
|
public Player winner () |
|
The
winning Player; returns null if the game is not over. |
|
ensure:if
this.gameOver() |
|
this.winner() != |
|
this.previousPlayer() |
|
|
|
|
|
|
public void setPileSize (int number) |
|
Set the
number of sticks in the pile. |
|
require:number
>= 0 |
|
ensure:this.sticksLeft()
== number |
|
|
|
public void setNextPlayer (Player player) |
|
Set
which Player takes the next turn. |
|
require:player
== one of the Players provided as constructor arguments. |
|
ensure:this.nextPlayer()
== player |
|
|
|
|
|
|
public void register (NimUI observer) |
|
Register
a user interface; user interface will be notified of GameManager state
changes. |
|
require:observer
!= null |
|
|
|
public void play () |
|
Play a
game of simple nim. |
|
|
|
|
|
|
public NimUI (GameManager theGame) |
|
Create a
new user interface for the specified GameManager. |
|
require:theGame
!= null |
|
|
|
public void update (GameManager target) |
|
Notify
this user interface of a state change in the specified GameManager. |
|
require:target
!= null |
|
|
|
public void start () |
|
Start
the interface. |
|
|
|
|
public class NimGame { |
|
public static void main (String[] args) { |
|
GameManager theGame = new GameManager |
|
(new Player(“Player 1”), |
|
new Player(“Player 2”)); |
|
NimUI theInterface = new NimUI |
|
(theGame); |
|
theInterface.start(); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
How to put together a complete, simple system. |
|
problem analysis |
|
specification |
|
design |
|
implementation |
|
testing |
|
maintenance |
|
Three basic subsystems : |
|
interface |
|
model |
|
data management |
|
|
|
|
|
Designing and implementing a simple “nim” game. |
|
Identifying classes |
|
assigning responsibilities |
|
determining fundamental relationships |
|
writing detailed specifications |
|
integration of the user interface with the model |
|
The observes relation. |
|
|
|
|
|