Title: Chapter 3: Designing interactive classes'
1Chapter 3 Designing interactive classes.
2Objectives
- After studying this chapter you should understand
the following - the role of responsibilities in the design of an
object - the categorization of an objects
responsibilities as knowing responsibilities or
doing responsibilities - the difference between local variables and
instance variables - the structure of a complete program in Java
- the structure of a test system
- the purpose of named constants.
3Objectives
- Also, you should be able to
- analyze the role a simple object plays in a given
problem and list its responsibilities - use Java to specify the features of an object
based on its responsibilities - use Java to implement a simple class that has
been specified - implement a complete Java program using a simple
text-based interface for an object - implement a simple tester for testing a class
implementation - define named constants.
4Designing with objects
- Two questions when we design an OO system
- what are the objects?
- what features should these objects have?
- Our Initial goal learn to design and implement
simple objects. - We will ssume objects are there for the picking.
5Designing with objects
- Objects are designed to support system
functionality. - System specification are distributed as
responsibilities to objects identified.
6Object responsibilities
- Think in terms of
- what object must know.
- what object must do.
7Object responsibilities
- Knowing responsibilities include
- knowing properties of the entity object is
modeling - knowing about other objects with which it needs
to cooperate.
8Object responsibilities
- Doing responsibilities include
- computing particular values
- performing actions that modify its state
- creating and initializing other objects
- controlling and coordinating the activities of
other objects.
9From responsibilities to class features
- Knowing responsibilities
- translate into data the object must maintain or
- Translate into queries.
- Doing responsibilities
- translate into commands or
- Translate into queries.
10Designing a class
- To design a class
- determine an objects responsibilities,
- classify them as knowing or doing
responsibilities.
11Example Design of Nim game
- Game Players take turns removing sticks from a
pile. Each player in turn removes one, two, or
three sticks. The player who removes the last
stick loses.
12Design of Nim game
- Two objects for the picking
- Player
- Pile of sticks
- Pile and Player are part of the model of problem.
- Model aspects of game independently of how is
presented to a user or how a user interacts with
it.
13Designing Pile
- Pile a very simple object
- keeps track of how many sticks remain.
- Pile responsibilities
- know
- number of sticks remaining
- do
- reduce number of sticks (remove sticks)
14Designing Player
- Player takes a turn in the game to remove
sticks from Pile. - Player responsibilities
- know
- this Players name.
- how many sticks this Player removed on his/her
most recent turn. - do
- take a turn by removing sticks from the Pile
15From knowing responsibilities to queries
- Class Pile
- queriessticks the number of sticks remaining in
this Pile, a non-negative integer
16From knowing responsibilities to queries
- Class Player
- queries
- name this Players name, a String
- sticksTaken number of sticks this Player
removed on his/her most recent turn ( 1, 2, or
3).
17From doing responsibilities to commands
- Class Pile
- commandsremove reduce number of sticks by
specified amount (number)
18From doing responsibilities to commands
- Class Player
- commandstakeTurn remove 1, 2, or 3 sticks from
the specified Pile (pile)
19Interaction diagramPlayer takes turn
20Pile, and Player constructors
- How are the Players name and the initial number
of sticks in the Pile determined? - Set these values when objects are
createdConstructors. - Constructors can have parameters
- Players name parameter in Players constructor.
- Initial number of sticks parameter in Pile
constructor.
21Pile specifications
- nimGame
- Class Pile
- public class Pile
- A pile of sticks for playing simple nim.
- Constructors
- public Pile (int sticks)
- Create a new Pile, with the specified number of
sticks. sticks must be non-negative.
22Pile specifications
- Queries
- public int sticks ()
- Number of sticks remaining in this Pile.
- Commands
- public void remove (int number)
- Reduce the number of sticks by the specified
amount. number must be non-negative and not
greater than the number of sticks remaining.
23Player specifications
- nimGame
- Class Player
- public class Player
- A player in the game simple nim.
- Constructors
- public Player (String name)
- Create a new Player with the specified name.
24Player specifications
- Queries
- public String name ()
- The name of this Player.
- public int sticksTaken ()
- The number of sticks this Player removed on this
Players most recent turn 1, 2, or 3.
25Player specifications
- Commands
- public void takeTurn (Pile pile)
- Remove 1, 2, or 3 sticks from the specified Pile.
26Implementing the class Pile
- Data maintained by Pile is number remaining
sticks.
private int sticksLeft // sticks left in the Pile
- Instance variable sticksLeft is initialized in
constructor and value returned by query sticks
- public Pile (int sticks)
- sticksLeft sticks
-
- public int sticks ()
- return sticksLeft
27Implementing the class Pile
- Command remove is specified with an int parameter
number, indicating sticks to be removed
public void remove (int number)
- Executing command reduces instance variable
sticksLeft by value client supplies in number.
public void remove (int number) sticksLeft
sticksLeft - number
28Implementing the class Player
- Player needs to know name and number of sticks
taken on most recent turn.
private String name // this Players
name private int sticksTaken // sticks taken on
this Players most recent turn
- Variables should be initialized in the
constructor.
public Player (String name) this.name
name this.sticksTaken 0
29Implementing the class Player
- Queries simply return the values of the instance
variables
public String name () return name public
int sticksTaken () return sticksTaken
30Invoking a method acting as client
- General form for invoking a query
objectReference.queryName(arguments)
- General form for invoking a command is
objectReference.commandName(arguments)
31Implementing Players takeTurn
/ Remove 1, 2, or 3 sticks from the
specified Pile. The Pile must not be empty.
/ public void takeTurn (Pile pile)
- takeTurn method must
- determine how many sticks to take
- Give Player the move strategy to take 1 stick.
- remove them from the Pile
- pile.remove(1)
- store the number removed in sticksTaken instance
variable. - sticksTaken 1
32Implementing Players takeTurn
- /
- Remove 1, 2, or 3 sticks from the specified
Pile. - The Pile must not be empty.
- /
- public void takeTurn (Pile pile)
- pile.remove(1)
- sticksTaken 1
-
33Interaction diagram Player commands a Pile
34Parameters v.s. arguments
- Arguments are provided in a method invocation by
expressions. Thus we could write something like - pile.remove(sticksTaken 1)
- or even
- pile.remove(2sticksTaken2)
35Parameters v.s. arguments
- Arguments must match in number, type and order
public void move (int direction, double distance)
- An invocation of move must provide two arguments,
an int and a double in that order.
object.move(90, 2.5)
36Commands and queries
- A command invocation is a form of statement.
- A query, which produces a value, is an
expression. - If myCounter is a Counter object and i an int,
i myCounter.currentCount() i
myCounter.currentCount()10
37Example Maze game
- Player must find his/her way through a set of
connected rooms to reach some goal. - there will be tricks player must figure out
- creatures of various kinds to be defeated along
the way.
38Example Maze game
- Objects for the picking
- player,
- maze denizens,
- rooms.
39Designing Explorer
- Explorer responsibilities
- know
- his/her name
- location in the maze
- amount of annoyance done when poking an opponent
- amount of annoyance he/she can endure before
being defeated.
40Designing Explorer
- Responsibilities into properties
- name name of the Explorer
- location room in which Explorer is in
- strength measure of Explorers offensive ability
- tolerance measure of what it takes to defeat
Explorer
41Designing Explorer
- Type of value for each Explorers property
- Name String
- Location Room
- Strength int
- Tolerance int
Explorer
String
String name
Room location
Room
int
strength
10
int
tolerance
100
42Designing Explorer
- Explorer responsibilities
- do
- change location in the maze (move from room to
room) - fight a maze Denizen
- commands to to perform these actions.
- move change location
- poke poke a Denizen
43Designing Explorer
- Both commands will have parameters
- move change location (new location)
- poke poke a Denizen (denizen to poke)
44Interaction diagram
45A constructor for the class Explorer
- Need constructor for creating Explorer instances.
- During creation properties must be initialized.
- Require values for name, location, strength, and
tolerance be provided as argument. - Constructor for Explorer has four parameters
create new Explorer (name, location, strength,
tolerance)
46Explorer specification
mazeGame Class Explorer public class Explorer A
maze game player. Constructors public Explorer
(String name, Room location, int strength, int
tolerance) Create a new Explorer with specified
name, initial location, strength,and
tolerance. Annoyance (hit points) required to
defeat this Explorer.
47Explorer specification
Queries public String name () Name of this
Explorer. public Room location () Room in which
this Explorer is currently located. public int
strength () Annoyance (hit points) this Explorer
causes when poking an opponent. public int
tolerance () Annoyance (hit points) required to
defeat this Explorer.
48Explorer specification
Commands public void move (Room newRoom) Move to
the specified Room. public void takeThat (int
hitStrength) Receive a poke of the specified
number of hit points. public void poke (Denizen
opponent) Poke the specified Denizen.
49Implementing class Explorer
- Explorer objects have four properties name,
location, strength, and tolerance. - Use instance variables to store these values
private String name // name private Room
location // current location private int
strength // current strength (hit
points) private int tolerance // current
tolerance (hit points)
- These variables are initialized in the
constructor.
50Implementing class Explorer
- Queries return current values of instance
variables. - Example query location returns value stored in
location.
public Room location () return location
51Implementing class Explorer
- Implementing method move, argument value is
stored in instance variable location
public void move (Room newRoom) location
newRoom
52Implementing class Explorer
- Method takeThat is similar to Pile method remove.
Argument value, hitStrength, is subtracted
from instance variable tolerance and stored in
tolerance
public void takeThat (int hitStrength)
tolerance tolerance - hitStrength
53Implementing class Explorer
- Method poke invokes Denizens method takeThat
public void poke (Denizen opponent)
opponent.takeThat(strength)
54Local variables in methods
- local variable method variable created as
part of method execution used to hold
intermediate results needed during computation.
55Local variables in methods
- Assume that RetailItem includes instance
variables, with the obvious meanings
private double basePrice private double
discountRate private double taxRate
- Want to implement RetailItem method netPrice
- public double netPrice ()
- The cost of this RetailItem after discount, and
including tax.
56Local variables in methods
- public double netPrice ()
- double discount
- double subtotal
- double tax
- discount basePrice discountRate
- subtotal basePrice - discount
- tax subtotal taxRate
- return subtotal tax
-
57Local variables
Instance variables
- Defined inside a method.
- Exists while method executes.
- Must be initialized before used. otherwise,
compiler error. - Accessed only from the method.
- Meaningful only during method execution.
- Contains some intermediate value needed only
during execution of method value is not part of
objects state.
- Defined outside any method.
- Exists as long as the object exists.
- Initialized in a constructor.
- Accessed from any class method.
- Has meaningful value during life of object,
whether or not object is actively doing
something. - Represents an objects property its value is
part of objects state.
58Putting together a complete system
- A complete system includes
- model
- user interface.
- Example
- model Rectangle instance displayed on a computer
screen use int to measure dimensions. - User interface object instance of class
RectangleViewer, with one command,
displayRectangle.
59Putting together a complete system
- displayRectangle writes Rectangles length,
width, area, and perimeter to the screen. - RectangleViewer queries Rectangle for display
data.
60Designing Rectangle
- Rectangle know
- Width
- Length
- Rectangle do
- Compute area
- Compute perimeter
61Rectangle specifications
- figures
- Class Rectangle
- public class Rectangle
- Constructors
- public Rectangle (int length, int width)
- Create a new Rectangle with the specified length
and width. - Queries
- public int length ()
- The length of this Rectangle.
- public int width ()
- The width of this Rectangle.
- public int area ()
- The area of this Rectangle.
- public int perimeter ()
- The perimeter of this Rectangle.
62Specifying RectangleViewer
- public void displayRectangle (Rectangle
rectangle) - Write the length, width, area, and perimeter of
the specified Rectangle to standard output.
63System.out.println
- Simple way to write output to the display.
- Object System.out has a method
public void println (String s) Write a line
containing the specified String to standard
output.
- Executing the method results in its argument
being written to the screen.
64Implementing displayRectangle
- public void displayRectangle (Rectangle
rectangle) - int outputValue
- outputValue rectangle.length()
- System.out.println("length " outputValue)
- outputValue rectangle.width()
- System.out.println("width " outputValue)
- outputValue rectangle.area()
- System.out.println("area " outputValue)
- outputValue rectangle.perimeter()
- System.out.println("perimeter " outputValue)
65main Method
- Need a public class, containing a method main.
- main method top-level method that initiates
execution of a system. - Method main is specified as
public static void main (String argv)
66main Method
- main used to
- Create Rectangle and RectangleViewer,
- Command RectangleViewer to display Rectangle.
67Main class
- /
- A simple system to display a Rectangles
properties. - /
- public class RectangleDisplay
- // Run the program.
- public static void main (String argv)
- Rectangle theModel
- RectangleViewer theUserInterface
- theModel new Rectangle(100,50)
- theUserInterface new RectangleViewer()
- theUserInterface.displayRectangle(theModel)
-
-
68The method toString
- Useful to include in model classes a query to
return a String representation of an objects
state. - In Java, this method is specified by convention
as
public String toString () A String representation
of the object.
69The method toString
- For example, define the method in the class
Rectangle
/ A String representation of this object.
/ public String toString () return
"Rectangle length " length " width "
width
70Testing
- Unit testing test class being implemented to
make sure it behaves as expected. - Functional testing test entire system to ensure
that it meets customers specifications.
71Test driven implementation
- Incremental test-driven implementation most
effective means of reducing time required to
track down and correct bugs. - Test-driven aspects
- The process is to code a little, test a little.
- Implementation is test-driven. write test for
a feature before implementing the feature.
72Test driven implementation example
- Stubbed implementation of TrafficSignal
public class TrafficSignal public static final
int GREEN 0 public static final int YELLOW
1 public static final int RED 2 private int
light public TrafficSignal () public int
light () return 0 public void change ()
Left blank
Dummy return value
Left blank
73TrafficSignalTest class
- TrafficSignalTest
- Client of TrafficSignal
- Creates instance of TrafficSignal
- Queries and commands TrafficSignal instance
- User interface object, reporting test results to
user.
74TrafficSignalTest class
- The only property of a TrafficSignalTest
properties - TrafficSignal to be tested.
- TrafficSignalTest function is to test the
TrafficSignal. - Specify a single command for the class
- public void runTest ()
- Test a TrafficSignal.
75TrafficSignalTest class
- How does the TrafficSignalTest get a
TrafficSignal to test? - TrafficSignal could be an argument, either to
TrafficSignalTest constructor or to method
runTest - TrafficSignal could be created by
TrafficSignalTest, either in its constructor or
in the method runTest
76TrafficSignalTest class
- class TrafficSignalTest
- private TrafficSignal signal // the object to
test - //Create a TrafficSignalTest
- public TrafficSignalTest ()
- signal new TrafficSignal()
-
- // Run the test.
- public void runTest ()
-
77The initializing class
- /
- A simple test system for the class
TrafficSignal. - /
- public class Test
- /
- Run a TrafficSignal test.
- /
- public static void main (String argv)
- TrafficSignalTest test
- test new TrafficSignalTest()
- test.runTest()
-
-
78Writing tests
- Use private methods testing each feature of
TrafficSignal. - Place invocations of these methods in runTest()
79testInitialState
private void testInitialState ()
System.out.println("testInitialState") Syste
m.out.println( "Initial light "
signal.light()) public void runTest ()
testInitialState()
- May run test, getting misleading correct results
class TrafficSignal has only been stubbed.
80TrafficSignal constructor and query
- For class TrafficSignal need to implement
- TrafficSignal constructor
- Query light testInitialState invokes it.
public TrafficSignal () light
TrafficSignal.GREEN //initial state public
int light () return light
- Run the test, getting correct result because we
have correctly implemented the constructor and
query.
81Testing command change
- Need to build a test for the command change.
- give the command at least three times and see
light cycle from green back to green. - Put this test in its own method and invoke it
from runTest
public void runTest () testInitialState() tes
tChange()
82Testing command change
- private void testChange ()
- System.out.println("testChange")
- System.out.println("Starting light "
signal.light()) - signal.change()
- System.out.println("After 1 change "
signal.light()) - signal.change()
- System.out.println("After 2 changes "
signal.light()) - signal.change()
- System.out.println("After 3 changes "
signal.light())
83Testing command change
- Recompiling and running TrafficSignalTest
produces
testInitialState Initial light
0 testChange Starting light 0 After 1 change
0 After 2 changes 0 After 3 changes 0
- Recall, change() is stubbed as a do-nothing
method.
84Implementing command change
public void change () light (light 1)
3
- Recompiling and running produces successful test.
85TrafficSignal and TrafficSignalTest
- Have simple test system for the class
TrafficSignal - Can modify existing implementation,
- Can add new tests to system,
- Existing tests will help ensure that additions or
modifications dont break implementation.
86Static methods
- Methods not dependent on the state of an object.
- Defined as static,
- Associated with the class rather with a class
instance.
87Static methods
- Predefined class Math methods are all static.
- Math includes a square root function specified
as
public static double sqrt (double a) The positive
square root of the specified value.
88Static method invocation
- A static function is invoked by prefixing the
name of the class rather than the name of a class
instance. - Diagonal method for Rectangle is written as
public double diagonal () double a
(double)(lengthlength widthwidth) return
Math.sqrt(a)
89Final features
- Class named constants are defined as static
final
public static final int GREEN 0
- Specification static implies that feature is
associated with the class not with an instance of
the class. - Keyword final means that value to which
identifier is bound cannot be changed. - Use class name when referring to feature
light TrafficSignal.GREEN
90Importing static features
- Can import static features of a class.
- Can import one static features.
import static Math.sqrt import static
TrafficSignal.GREEN
- This allows imported identifiers to be used
without being prefixed with the class name
return sqrt(a) light GREEN
91Importing static features
- Can import static features of a class.
- Can import all static features defined in a
class.
import static Math. import static
TrafficSignal.
- This allows imported identifiers to be used
without being prefixed with the class name
92Summary
- designing with objects.
- ask what should the object know and what should
the object do. - enumerate the knowing responsibilities and the
doing responsibilities of the object.
93Summary
- Object responsibilities are determined by the
objects role in supporting the functionality of
the system. - System functionality is distributed to the
comprising objects by assigning a set of
responsibilities to each object.
94Summary
- Knowing responsibilities translate to queries
when the object is defined. - Doing responsibilities translate into queries
or commands. - Itemizing an objects responsibilities determines
the objects features and its relationship to
other objects that comprise the system.
95Summary
- We developed several examples in which one object
acts as client to another. - Client object was provided with a reference to a
server as a method argument. - Client was then able to use server by invoking
its methods.
96Summary
- A command invocation is a form of statement.
- The format for invoking a command is
object.command (arguments)
- Processor executes method body associated with
command, which generally results in the object
changing state.
97Summary
- A query invocation is a form of expression,
since it computes and returns value. - The format is similar to a command invocation
object.query (arguments)
98Summary
- A constructor invocation creates a new object,
and returns a reference to the newly created
object. - The format is
new class (arguments)
99Summary
- When a method with formal parameters is invoked,
- method variable is allocated for each formal
parameter - Method initialized with the argument provided by
the client. - A local variable is another kind of method
variable. - Local variables are created when a method is
invoked - used to hold intermediate results needed during
the computation.
100Summary
- Method variables are different from instance
variables. - Instance variables
- contain data that is part of the objects state.
- They are created when the object is created,
- should always contain a meaningful value.
- Method variables
- created when a method is invoked,
- contain values that are used only for a specific
computation.
101Summary
- Developed a simple but complete system containing
- a model object
- user interface object.
- To complete program, introduced a class with a
single method named main.
102Summary
- main is the method that is executed when the
program is run. - Its only function is to create the initial
objects and get the system started.
103Summary
- In example,
- main creates a model object ,
- main creates user interface object,
- main starts user interface, passing it model as
argument.
104Summary
- We concluded with a brief introduction to unit
testing. - To reduce time spent debugging and improve
programmer efficiency, we adopt a test-driven
implementation strategy. - Idea develop a test for each feature or bit of
functionality before implementing the feature or
adding the functionality.
105Summary
- We construct a class to be used to test another
existing class. - An instance of testing class invokes commands and
queries of object under test, and displays
information about its state. - By comparing actual results with expected results
we can determine if the object under test behaves
correctly.