Download Chapter 7 : Building a Text

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
An Introduction to
Programming and Object
Oriented Design using Java
2nd Edition. May 2004
Jaime Niño
Frederick Hosch
Chapter 7 : Building a Text-based user
interface.
Objectives
 After studying this chapter you should understand the
following:
 independence of servers from clients;
 likeliness of the user interface to change;
 i/o streams;
 structure of a simple text-based user interface;
 purpose and structure of a while loop;
 how existing classes can be composed to define a new
class.
May 2004
Chapter 7
1
Objectives
 Also, you should be able to:
 use input/output objects to read and write data;
 build a simple text-based user interface;
 use and trace a basic while statement;
 define classes whose implementations contain other classes
as components.
May 2004
Chapter 7
2
Relating User-interface and
Model
 Model: objects that solve problem at hand.
 User interface: interacts with user, getting input from user,
and giving output to user, reporting on status of model.
User Interface
controls, views
Model
Flexibility in design: identifying these as separate subsystems.
May 2004
Chapter 7
3
Stream-based I/O
 Data streams: sequence of bytes.
 character stream: sequence of characters
 input stream: stream is a source of data for an application.
 output stream: stream is application destination (or sink).
…b b bb bb b bb …
…b b bb bb b bb …
Application
…b b bb bb b bb …
May 2004
…b b bb bb b bb …
Chapter 7
4
Standard Input and Output streams
standard input:
characters from keyboard
standard output:
characters to display
Application
standard error:
characters to display
May 2004
Chapter 7
5
Writing standard output
 System.out: provides methods for writing to standard
output.
public void println (String s)
Write specified String to standard output and then terminate the line.
public void print (String s)
Write the specified String to standard output.
public void println ()
Terminate current line by writing line terminator to standard output.
public void flush ()
Flush stream: write buffered output to standard output and flush that stream.
May 2004
Chapter 7
6
Input : java.util.Scanner
 Scanner
 reads characters from a character input stream.
 Input stream specified when Scanner is created.
public Scanner (InputSource source)
Create a Scanner to read from specified source.
 Input source:
 Assume characters are keyed from keyboard.
 Use System.in
May 2004
Chapter 7
7
Input : java.util.Scanner
 To create a Scanner reading from System.in
 import java.util.Scanner
Scanner input = new Scanner(System.in);
Create a Scanner to read from specified source.
 Scanner
 Sees input as a sequence of tokens separated by
white space.
 White space: spaces, tabs, line terminators, …
 Skips all white space before a token.
May 2004
Chapter 7
8
Input : java.util.Scanner
 Scanner
 Sees input as a sequence of tokens separated by
white space.
 White space: spaces, tabs, line terminators, …
 If user keys in: (  means space)
23  -34  5ab c?
token
May 2004
token
token
Chapter 7
token
9
Input : java.util.Scanner
 Given the data input stream:
23  -34  5ab c?
token
token
token
token
 Tokens can be read in using the methods:
public
public
public
public
May 2004
String next()
boolean nextBoolean()
int nextInt()
double nextDouble()
Chapter 7
10
Input : java.util.Scanner
 Need 4 invocations of next() to read whole line:
23  -34  5ab c?
token
token
token
token
 Invoking next() will return tokens as strings:
String
String
String
String
one = input.next();
two = input.next();
three = input.next();
four = input.next();
//
//
//
//
one contains “23”
two contains “-34”
three contains “5ab”
four contains “c?”
 next() is a query : returns a String token.
 next() is a command: changes state of Scanner
May 2004
Chapter 7
11
Input: java.util.Scanner
 If there are no tokens in the input stream, it
will wait until user keys in a line with nonblank characters.
 An input stream can be closed with the
command close().
 If an input stream is closed or terminated
attempting to read it will fail.
May 2004
Chapter 7
12
Input: java.util.Scanner
 The methods
 nextBoolean()
 nextInt()
 nextDouble()
 Have preconditions: token of form specified
by method used, otherwise fails.
 To verify these preconditions use:
 hasNextBoolean()
 hasNextInt()
 hasNextDouble()
May 2004
Chapter 7
13
Input: java.util.Scanner
 After reading some input tokens, you can skip
the rest of the input tokens in the current
line with the method:
public String nextLine()
advances past the current line and returns
any input that was skipped excluding the’
line terminator.
May 2004
Chapter 7
14
Building an interface for
Rectangle
 Build an interface that let’s user specify dimensions
of the Rectangle and ask for property to be displayed.
class RectangleTUI
A simple text-based interface for Rectangles.
public RectangleTUI ()
Create a new RectangleTUI instance.
public void start ()
Run the interface.
May 2004
Chapter 7
15
Building an interface for
Rectangle
 Application creates interface and executes start:
public class RectangleExample {
public static void main (String[] argv) {
(new RectangleTUI()).start();
}
}
May 2004
Chapter 7
16
Building an interface for
Rectangle
RectangleTUI properties:
private Rectangle rectangle;
// the model
private Scanner in;
//standard input
 Instance variables are initialized in constructor:
public RectangleTUI () {
this.rectangle = null;
this.in = new Scanner(System.in);
}
May 2004
Chapter 7
17
Building an interface for
Rectangle
private void createRectangle ()
Create a new Rectangle with user-provided dimensions.
Uses readIntWithPrompt to get dimensions from user.
To get Rectangle dimensions from user:
private int readIntWithPrompt (String prompt) {
System.out.print(prompt); System.out.flush();
int input = in.nextInt();
in.nextLine();
return input;
}
May 2004
Chapter 7
18
Building an interface for
Rectangle
private void createRectangle () {
int length;
int width;
length = readIntWithPrompt(
"Rectangle length (a non-negative integer): ");
width = readIntWithPrompt(
"Rectangle width (a non-negative integer): ");
this.rectangle = new Rectangle(length,width);
}
May 2004
Chapter 7
19
Building an interface for
Rectangle
 RectangleTUI is a client of Rectangle.
 Constructor creates an instance of Rectangle using input
values from user.
 But, Rectangle has pre-conditions to keep:
public Rectangle (int length, int width)
Create a new Rectangle with specified length and width.
require: length >= 0 &&
width >= 0
User may enter negative values for length or width.
May 2004
Chapter 7
20
While statement
while ( condition )
statement
B E G IN
true
condition
false
statement
EN D
May 2004
Chapter 7
21
Re-implementing createRectangle
private void createRectangle () {
//initialize to insure at least one execution of loops:
int length = -1;
int width = -1;
while (length < 0)
length = readIntWithPrompt(
"Rectangle length (a non-negative integer): ");
while (width < 0)
width = readIntWithPrompt(
"Rectangle width (a non-negative integer): ");
// assert: length >=0 && width >= 0
this.rectangle = new Rectangle(length,width);
}
May 2004
Chapter 7
22
Building an interface for
Rectangle
private void displayMenu ()
Display the menu to the user.
private void executeChoice (int choice)
Perform the indicated action, and display results to the user.
May 2004
Chapter 7
23
Building an interface for
Rectangle
 Name operation choices with identifiers:
private static final int LENGTH = 1;
private static final int WIDTH = 2;
private static final int AREA = 3;
private static final int PERIMETER = 4;
private static final int NEW = 5;
private static final int EXIT = 0;
private static final int NO_CHOICE = -1;
May 2004
Chapter 7
24
Building an interface for
Rectangle
public void start () {
createRectangle();
int choice = NO_CHOICE;
while (choice!= EXIT) {
displayMenu();
choice= readIntWithPrompt("Enter choice: ");
executeChoice(choice);
}
}
May 2004
Chapter 7
25
Building an interface for
Rectangle
private void displayMenu () {
System.out.println();
System.out.println("Enter number denoting action to perform:");
System.out.println("Display length............." + LENGTH);
System.out.println("Display width.............." + WIDTH);
System.out.println("Display area..............." + AREA);
System.out.println("Display perimeter.........." + PERIMETER);
System.out.println("Create new rectangle......." + NEW);
System.out.println("Exit......................." + EXIT);
}
May 2004
Chapter 7
26
Building an interface for Rectangle
private void executeChoice (int choice) {
System.out.println();
if (choice == LENGTH)
System.out.println("Length is " + rectangle.length());
else if (choice == WIDTH)
System.out.println("Width is " + rectangle.width());
else if (choice == AREA)
System.out.println("Area is " + rectangle.area());
else if (choice == PERIMETER)
System.out.println("Perimeter is " +
rectangle.perimeter());
else if (choice == NEW)
createRectangle();
else if (choice == EXIT)
System.out.println("Goodbye.");
else
System.out.println(choice + " is not valid.");
}
May 2004
Chapter 7
27
Using composition
 Build an application that lets a user access a “locked
oracle.”
 user can get a fortune from oracle only by providing
correct key.
 Use classes CombinationLock and Oracle.
 Create two new classes,
 one modeling a locked oracle, and
 other defining user interface.
May 2004
Chapter 7
28
Using composition
public class Oracle
A dispenser of fortunes. An Oracle gives a fortune only if it is awake;
normal sequence of actions is: wake Oracle; get fortune; put the
Oracle back to sleep.
public Oracle ()
Create new Oracle. This Oracle is initially asleep.
ensure: !this.isAwake()
public boolean isAwake ()
This Oracle is awake.
public String fortune ()
The prophecy currently seen by this Oracle.
require: this.isAwake()
public void awaken ()
Wake this Oracle. Oracle will divine a fortune when it wakes.
public void sleep ()
Put this Oracle to sleep.
May 2004
Chapter 7
29
Using composition
public class LockedOracle
A keyed dispenser of fortunes. A LockedOracle will give a fortune only if the
correct key is provided. A LockedOracle must be told to conjure a fortune
before the fortune can be retrieved.
public static final String NO_FORTUNE
String indicating no fortune has been conjured.
public LockedOracle (int key)
Create new LockedOracle with the specified key.
require: 0 <= key && key <= 999
public String fortune ()
The prophecy currently seen by this LockedOracle. If a fortune has
not been conjured, the String NO_FORTUNE is returned.
public void conjureFortune (int keyToTry)
Prophesy. This LockedOracle will make a prophecy only if the
correct key is presented.
require: 0 <= keyToTry && keyToTry <= 999
May 2004
Chapter 7
30
Using composition
 Composition: process of defining a new class by putting
together existing classes.
 An instance of the new class, the composite, references
instances of the existing classes, its components.
CompositeClass
May 2004
has-a
Chapter 7
ComponentClass
31
Implementing LockedOracle
 LockedOracle class defined to be a composite, with
CombinationLock and Oracle components.
Or acle
LockedOracle
CombinationLock
May 2004
Chapter 7
32
Implementing LockedOracle
private CombinationLock lock;
private Oracle oracle;
private String fortune; //current prophesy
public static final String NO_FORTUNE =
"Sorry, no fortune for you.";
 Instance variables are initialized in constructor:
public LockedOracle (int key) {
lock = new CombinationLock(key);
lock.close();
oracle = new Oracle();
fortune = NO_FORTUNE;
}
May 2004
Chapter 7
33
Implementing LockedOracle
public String fortune () {
return this.fortune;
}
 Command conjureFortune first attempts to open lock, and wakes
oracle only if it succeeds:
public void conjureFortune (int keyToTry) {
lock.open(keyToTry);
if (lock.isOpen()) {
oracle.awaken();
fortune = oracle.fortune();
oracle.sleep();
lock.close();
} else
fortune = NO_FORTUNE;
}
May 2004
Chapter 7
34
Implementing the User interface
class LockedOracleTUI
A simple text-based interface for a LockedOracle.
public LockedOracleTUI (LockedOracle oracle)
Create a new interface for the specified LockedOracle.
public void start ()
Run the interface.
May 2004
Chapter 7
35
Implementing the User interface
 Application creates an oracle and an interface, and
executes interface’s start method:
public class OracleExample {
public static void main (String[] argv) {
LockedOracle oracle = new LockedOracle(123);
LockedOracleTUI ui = new
LockedOracleTUI(oracle);
ui.start()
}
}
May 2004
Chapter 7
36
Implementing the User interface
 Instance variables and constructor.
private LockedOracle oracle;
private Scanner in;
public LockedOracleTUI (LockedOracle oracle) {
this.oracle = oracle;
this.in = new Scanner(System.in);
}
May 2004
Chapter 7
37
Implementing the User interface
 Specify private helper methods:
private boolean readYes (String prompt)
Read a yes or no response from the user. Return true if user keys “yes.”
private int readKey (String prompt)
Read and return a legal key.
ensure:
0 <= this.readKey() && this.readKey() <= 999
May 2004
Chapter 7
38
Implementing the User interface
public void start () {
String fortune;
boolean goOn = true;
while (goOn) {
goOn = readYes("Fortune? (Key yes or no): ");
if (goOn) {
int key = readKey("Enter key (0-999): ");
oracle.conjureFortune(key);
fortune = oracle.fortune();
System.out.println(fortune);
System.out.println();
}
}
System.out.println("Good-bye.");
}
May 2004
Chapter 7
39
Summary
 Built a simple text-based user interface.
 We reviewed the relationship between client and
server:
 a client is dependent on its server,
 a server is independent of its client.
May 2004
Chapter 7
40
Summary
 In designing a system, it is preferable to make stable
components independent of those likely to require
change.
 Since user interface is considerably less stable than
model, we favor designs in which the user interface
acts as client to the model.
 In cases where model must collaborate with the user
interface, need to minimize interface for this
collaboration.
May 2004
Chapter 7
41
Summary
 Introduced i/o streams.
 A stream is a sequence of bytes, sometimes viewed as
characters, to which an application can append data (an output
stream) or from which an application can read data (an input
stream).
 Java has an extensive library of classes to deal with streams.
 Use only basic functionality
 from the predefined object System.out for output,
 Scanner class from java.util package for input.
May 2004
Chapter 7
42
Summary
 Presented two simple applications with their textbased user interfaces.
 Introduced while statement or while-loop: a
Java construct that specifies a sequence of actions to
be repeated until a condition fails to hold.
May 2004
Chapter 7
43
Summary
 In design of LockedOracle composed existing
classes to construct a new class.
 The relation between a composite class and its
component classes is called the has-a relation.
 LockedOracle class wraps Oracle, adapting its
specification to that required by the system: the
adapter pattern.
May 2004
Chapter 7
44