Object Oriented Design and Patterns
Object Oriented Design and Patterns
Cay S. Horstmann
Chapter 1
Chapter Topics
Hello, World in Java
Documentation Comments
Primitive Types
Control Flow Statements
Object References
Parameter Passing
Packages
Basic Exception Handling
Strings
Reading Input
Array Lists and Linked Lists
Arrays
Static Fields and Methods
Programming Style
1
"Hello, World" in Java
Simple but typical class
Ch1/helloworld/Greeter.java
Features:
o Constructor Greeter(String aName)
o Method sayHello()
o Instance field name
Each feature is tagged public or private
new Greeter("World")
new Greeter("World").sayHello()
Ch1/helloworld/GreeterTest.java
2
Open a shell window
cd to directory that holds your files
Compile and run
javac GreeterTest.java
java GreeterTest
Using BlueJ
Download BlueJ from http://www.bluej.org
No test program required
Select Project->New and supply directory name
Click on New Class... and type in Greeter class
Compile the class
Right-click the class to construct an object
Right-click the object to invoke a method
Using BlueJ
3
Documentation Comments
Delimited by /** ... */
First sentence = summary
@param parameter explanation
@return explanation
Javadoc utility extracts HTML file
4
Documentation Comments - Detail
5
Documentation Comments
Easy to keep documentation in sync with code
You must document all classes and methods
The pros do it--check out the API docs
Install and bookmark the API docs now!
6
Primitive Types
8 primitive types
int, long, short, byte
double, float
char
boolean
suffixes L = long, F = float
character constants 'a', '\n', '\x2122'
Casts (int) x, (float) x
Math class has methods that operate on numbers:
y = Math.sqrt(x);
Control Flow
if
while
do/while
for
Variable can be declared in for loop:
7
Object References
Object variable holds a reference
Greeter worldGreeter = new Greeter("World");
anotherGreeter.setName("Dave");
// now worldGreeter.sayHello() returns "Hello, Dave!"
worldGreeter = null;
if (worldGreeter == null) . . .
8
Refers to implicit parameter of method call
Example: Equality testing
Example: Constructor
Parameter Passing
Java uses "call by value":
Method receives copy of parameter value
Copy of object reference lets method modify object
No Reference Parameters
Java has no "call by reference"
public void copyLengthTo(int n)
{
n = name.length();
}
public void copyGreeterTo(Greeter other)
{
other = new Greeter(name);
}
9
Neither call has any effect after the method returns
int length = 0;
worldGreeter.copyLengthTo(length); // length still 0
worldGreeter.copyGreeterTo(daveGreeter) // daveGreeter unchanged
Packages
Classes are grouped into packages
Package names are dot-separated identifier sequences
java.util
javax.swing
com.sun.misc
edu.sjsu.cs.cs151.alice
Packages
Add package statement to top of file
package edu.sjsu.cs.cs151.alice;
public class Greeter { . . . }
java.util.ArrayList
javax.swing.JOptionPane
Importing Packages
Tedious to use full class names
import allows you to use short class name
import java.util.ArrayList;
. . .
ArrayList a; // i.e. java.util.ArrayList
import java.util.*;
Importing Packages
Cannot import from multiple packages
10
import java.*.*; // NO
import java.util.*;
import java.sql.*;
. . .
java.util.Date d; // Date also occurs in java.sql
edu.sjsu.cs.sjsu.cs151.alice.Greeter
must be in subdirectory
basedirectory/edu/sjsu/cs/sjsu/cs151/alice
javac edu/sjsu/cs/sjsu/cs151/alice/Greeter.java
or
javac edu\sjsu\cs\sjsu\cs151\alice\Greeter.java
java edu.sjsu.cs.cs151.alice.GreeterTest
Exception Handling
Example: NullPointerException
11
String name = null;
int n = name.length(); // ERROR
Catching Exceptions
try
{
code that might throw an IOException
}
catch (IOException exception)
{
12
take corrective action
}
Corrective action can be:
o Notify user of error and offer to read another file
o Log error in error report file
o In student programs: print stack trace and exit
exception.printStackTrace();
System.exit(1);
Strings
Sequence of Unicode characters
length method yields number of characters
"" is the empty string of length 0, different from null
charAt method yields characters:
char c = s.charAt(i);
Strings
substring method yields substrings:
"Hello".substring(1, 3) is "el"
StringTokenizer
13
Use StringTokenizer to break string into substrings
String concatenation
+ operator concatenates strings:
int n = 7;
String greeting = "Hello, " + n;
// yields "Hello, 7"
Reading Input
Use input dialog:
14
If user cancels, result is null:
Reading Input
Must call System.exit(0)
Ch1/input1/InputTest.java
Also have message dialog
Reading Input
Read console input from System.in
System.in is an InputStream: reads bytes
We want a Reader that reads characters
Turn System.in into InputStreamReader
Also want to read entire lines
Use BufferedReader:
Ch1/input2/InputTest.java
15
Collects objects of any class type
add appends to the end
Linked Lists
Efficient insertion and removal
16
LinkedList countries = new LinkedList();
countries.add("Belgium");
countries.add("Italy");
countries.add("Thailand");
List Iterators
Iterator points between list elements
Arrays
Drawback of array lists: can't store numbers
Arrays can store objects of any type, but their length is fixed
int[] numbers = new int[10];
17
Array variable is a reference
Arrays
length member yields number of elements
Command-Line Arguments
void main(String[] args)
args parameter of main is initialized with command-line arguments
Example:
java GreeterTest Mars
18
args.length is 1
args[0] is "Mars"
Static Fields
Shared among all instances of a class
Example: shared random number generator
Static Methods
Don't operate on objects
Example: Math.sqrt
Example: factory method
Greeter g = Greeter.getRandomInstance();
19
name
sayHello
Classes:
start with uppercase, use caps for new words:
Greeter
ArrayList
Constants:
use all caps, underscores to separate words
PI
MAX_VALUE
String getName()
void setName(String newValue)
20
private String name;
public Greeter(String aName) { . . . }
. . .
}
No magic numbers
21
Object-Oriented Design & Patterns
Cay S. Horstmann
Chapter 2
Chapter Topics
From Problem to Code
The Object and Class Concepts
Identifying Classes
Identifying Responsibilities
Relationships Between Classes
Use Cases
CRC Cards
UML Class Diagrams
Sequence Diagrams
State Diagrams
Using javadoc for Design Documentation
Case Study: A Voice Mail System
22
Three Phases:
Analysis
Design
Implementation
Analysis Phase
Functional Specification
Design Phase
Goals
Identify classes
Identify behavior of classes
Identify relationships among classes
Artifacts
Implementation Phase
Implement and test classes
Combine classes into program
Avoid "big bang" integration
Prototypes can be very useful
23
o Behavior
o Identity
Class: Collection of similar objects
Identifying Classes
Rule of thumb: Look for nouns in problem description
Mailbox
Message
User
Passcode
Extension
Menu
Identifying Classes
Focus on concepts, not implementation
Categories of Classes
Tangible Things
Agents
Events and Transactions
Users and Roles
Systems
System interfaces and devices
Foundational Classes
Identifying Responsibilities
Rule of thumb: Look for verbs in problem description
Behavior of MessageQueue:
Responsibilities
24
OO Principle: Every operation is the responsibility of a single class
Example: Add message to mailbox
Who is responsible: Message or Mailbox?
Class Relationships
Dependency ("uses")
Aggregation ("has")
Inheritance ("is")
Dependency Relationship
C depends on D: Method of C manipulates objects of D
Example: Mailbox depends on Message
If C doesn't use D, then C can be developed without knowing about D
Coupling
Minimize dependency: reduce coupling
Example: Replace
with
Aggregation
Object of a class contains objects of another class
Example: MessageQueue aggregates Messages
Example: Mailbox aggregates MessageQueue
Implemented through instance fields
Multiplicities
1 : 1 or 1 : 0...1 relationship:
25
1 : n relationship:
Inheritance
More general class = superclass
More specialized class = subclass
Subclass supports all method interfaces of superclass (but implementations may
differ)
Subclass may have added methods, added state
Subclass inherits from superclass
Example: ForwardedMessage inherits from Message
Example: Greeting does not inherit from Message (Can't store greetings in
mailbox)
Use Cases
Analysis technique
Each use case focuses on a specific scenario
Use case = sequence of actions
Action = interaction between actor and computer system
Each action yields a result
Each result has a value to one of the actors
Use variations for exceptional situations
26
7. System places message in mailbox
Variation #2
CRC Cards
CRC = Classes, Responsibilities, Collaborators
Developed by Beck and Cunningham
Use an index card for each class
Class name on top of card
Responsibilities on left
Collaborators on right
CRC Cards
CRC Cards
27
Responsibilities should be high level
1 - 3 responsibilities per card
Collaborators are for the class, not for each responsibility
Walkthroughs
Use case: "Leave a message"
Caller connects to voice mail system
Caller dials extension number
"Someone" must locate mailbox
Neither Mailbox nor Message can do this
New class: MailSystem
Responsibility: manage mailboxes
Walkthroughs
UML Diagrams
UML = Unified Modeling Language
Unifies notations developed by the "3 Amigos" Booch, Rumbaugh, Jacobson
Many diagram types
We'll use three types:
o Class Diagrams
o Sequence Diagrams
o State Diagrams
Class Diagrams
28
Rectangle with class name
Optional compartments
o Attributes
o Methods
Include only key attributes and methods
Class Diagrams
Class Relationships
Multiplicities
29
any number (0 or more): *
one or more: 1..*
zero or one: 0..1
exactly one: 1
Composition
Special form of aggregation
Contained objects don't exist outside container
Example: message queues permanently contained in mail box
Association
Some designers don't like aggregation
More general association relationship
Association can have roles
Association
Some associations are bidirectional
Can navigate from either class to the other
Example: Course has set of students, student has set of courses
Some associations are directed
Navigation is unidirectional
Example: Message doesn't know about message queue containing it
30
Interface Types
Interface type describes a set of methods
No implementation, no state
Class implements interface if it implements its methods
In UML, use stereotype «interface»
Tips
Use UML to inform, not to impress
Don't draw a single monster diagram
Each diagram must have a specific purpose
Omit inessential details
Sequence Diagrams
Each diagram shows dynamics of scenario
Object diagram: class name underlined
Self call
31
Object Construction
State Diagram
Use for classes whose objects have interesting states
32
Design Documentation
Recommendation: Use Javadoc comments
Leave methods blank
/**
Adds a message to the end of the new messages.
@param aMessage a message
*/
public void addMessage(Message aMessage)
{
}
33
1. User dials main number of system
2. System speaks prompt
34
Use Case: Retrieve Messages
Variation #1
35
Some obvious classes
Mailbox
Message
MailSystem
36
Telephone
Who interacts with user?
Telephone takes button presses, voice input
Telephone speaks output to user
Telephone
Connection
With whom does Telephone communicate
With MailSystem?
What if there are multiple telephones?
Each connection can be in different state
(dialing, recording, retrieving messages,...)
Should mail system keep track of all connection states?
Better to give this responsibility to a new class
Connection
37
Analyze Use Case: Leave a message
1. User dials extension. Telephone sends number to Connection
(Add collaborator Telephone to Connection)
2. Connection asks MailSystem to find matching Mailbox
3. Connection asks Mailbox for greeting
(Add responsibility "manage greeting" to Mailbox,
add collaborator Mailbox to Connection)
4. Connection asks Telephone to play greeting
5. User speaks greeting. Telephone asks Connection to record it.
(Add responsibility "record voice input" to Connection)
6. User hangs up. Telephone notifies Connection.
7. Connection constructs Message
(Add card for Message class,
add collaborator Message to Connection)
8. Connection adds Message to Mailbox
38
Result of Use Case Analysis
39
Analyse Use Case: Retrieve messages
1. User types in passcode. Telephone notifies Connection
2. Connection asks Mailbox to check passcode.
(Add responsibility "manage passcode" to Mailbox)
3. Connection sets current mailbox and asks Telephone to speak menu
4. User selects "retrieve messages". Telephone passes key to Connection
5. Connection asks Telephone to speak menu
6. User selects "listen to current message". Telephone passes key to Connection
7. Connection gets first message from current mailbox.
(Add "retrieve messages" to responsibility of Mailbox).
Connection asks Telephone to speak message
8. Connection asks Telephone to speak menu
9. User selects "save current message". Telephone passes key to Connection
10. Connection tells Mailbox to save message
(Modify responsibility of Mailbox to "retrieve,save,delete messages")
11. Connection asks Telephone to speak menu
40
CRC Summary
One card per class
Responsibilities at high level
Use scenario walkthroughs to fill in cards
Usually, the first design isn't perfect.
(You just saw the author's third design of the mail system)
Dependency Relationships
41
Aggregation Relationships
A mail system has mailboxes
A mailbox has two message queues
A message queue has some number of messages
A connection has a current mailbox.
A connection has references to a mailsystem and a telephone
42
Interpreting a Sequence Diagram
Each key press results in separate call to dial, but only one is shown
Connection wants to get greeting to play
Each mailbox knows its greeting
Connection must find mailbox object:
Call findMailbox on MailSystem object
Parameters are not displayed (e.g. mailbox number)
Return values are not displayed (e.g. found mailbox)
Note that connection holds on to that mailbox over multiple calls
43
Connection State Diagram
Java Implementation
44
Ch2/mail/Message.java
Ch2/mail/MessageQueue.java
Ch2/mail/Mailbox.java
Ch2/mail/Connection.java
Ch2/mail/MailSystem.java
Ch2/mail/Telephone.java
Ch2/mail/MailSystemTest.java
45
Object-Oriented Design & Patterns
Cay S. Horstmann
Chapter 3
Chapter Topics
An overview of the Date classes in the Java library
Designing a Day class
Three implementations of the Day class
The importance of encapsulation
Analyzing the quality of an interface
Programming by contract
Unit testing
46
System.out.println(now.toString());
// prints date such as
// Sat Feb 03 16:34:10 PST 2001
Points in Time
47
Many calendars in use:
o Gregorian
o Contemporary: Hebrew, Arabic, Chinese
o Historical: French Revolutionary, Mayan
48
Designing a Day Class
daysFrom computes number of days between two days:
int n = today.daysFrom(birthday);
addDays computes a day that is some days away from a given day:
Mathematical relationship:
d.addDays(n).daysFrom(d) == n
d1.addDays(d2.daysFrom(d1)) == d2
(d + n) - d == n
d1 + (d2 - d1) == d2
49
o February has 28 days, except in leap years it has 29 days
o All other months have 31 days
o Leap years are divisible by 4, except after 1582, years divisible by 100 but
not 400 are not leap years
o There is no year 0; year 1 is preceded by year -1
o In the switchover to the Gregorian calendar, ten days were dropped:
October 15, 1582 is preceded by October 4
Second Implementation
For greater efficiency, use Julian day number
Used in astronomy
Number of days since Jan. 1, 4713 BCE
May 23, 1968 = Julian Day 2,440,000
Greatly simplifies date arithmetic
Ch3/code/day2/Day.java
Third Implementation
Now constructor, accessors are inefficient
Best of both worlds: Cache known Julian, y/m/d values
Ch3/code/day3/Day.java
Which implementation is best?
d.year
with
d.getYear()
o How about
50
d.year++?
o d = new Day(d.getDay(), d.getMonth(), d.getYear() + 1)
oUgh--that gets really inefficient in Julian representation
Don't use public fields, even for "simple" classes
class Employee
{
. . .
public String getName() { return name; }
public double getSalary() { return salary; }
public Date getHireDate() { return hireDate; }
51
private String name;
private double salary;
private Date hireDate;
}
Employee harry = . . .;
Date d = harry.getHireDate();
d.setTime(t); // changes Harry's state!!!
52
If we call a method to access an object, we don't expect the object to mutate
Rule of thumb:
Mutators should return void
Example of violation:
StringTokenizer t = . . .;
String s = t.nextToken();
String getToken();
void nextToken();
String getToken();
String nextToken(); // returns current
Side Effects
Accessor: no change to object
Mutator: changes object state
Side effect: change to another object
o Parameter variable
o static object
Avoid side effects--they confuse users
Good example, no side effect:
a.addAll(b)
Side Effects
Date formatting (basic):
53
SimpleDateFormat formatter = . . .;
String dateString = "January 11, 2012";
Date d = formatter.parse(dateString);
Advanced:
FieldPosition position = . . .;
Date d = formatter.parse(dateString, position);
Side Effects
Avoid modifying static objects
Example: System.out
Don't print error messages to System.out:
if (newMessages.isFull())
System.out.println("Sorry--no space");
Law of Demeter
Example: Mail system in chapter 2
Mailbox currentMailbox = mailSystem.findMailbox(...);
Breaks encapsulation
Suppose future version of MailSystem uses a database
Then it no longer has mailbox objects
Common in larger systems
Karl Lieberherr: Law of Demeter
Demeter = Greek goddess of agriculture, sister of Zeus
Law of Demeter
The law: A method should only use objects that are
o instance fields of its class
o parameters
o objects that it constructs with new
Shouldn't use an object that is returned from a method call
Remedy in mail system: Delegate mailbox methods to mail system
mailSystem.getCurrentMessage(int mailboxNumber);
mailSystem.addMessage(int mailboxNumber, Message msg);
. . .
Rule of thumb, not a mathematical law
54
Quality of Class Interface
Customers: Programmers using the class
Criteria:
o Cohesion
o Completeness
o Convenience
o Clarity
o Consistency
Engineering activity: make tradeoffs
Cohesion
Class describes a single abstraction
Methods should be related to the single abstraction
Bad example:
Completeness
Support operations that are well-defined on abstraction
Potentially bad example: Date
Convenience
A good interface makes all tasks possible . . . and common tasks simple
Bad example: Reading from System.in
Why doesn't System.in have a readLine method?
After all, System.out has println.
55
Why can't I make a BufferedReader from an input stream?
After all, I can make a PrintWriter from an output stream.
Clarity
Confused programmers write buggy code
Bad example: Removing elements from LinkedList
Reminder: Standard linked list class
Clarity
Iterator between elements
Like blinking caret in word processor
add adds to the left of iterator (like word processor):
Add X before B:
Consistency
Related features of a class should have matching
o names
o parameters
o return values
o behavior
56
Bad example:
Consistency
Bad example: String class
s.equals(t) / s.equalsIgnoreCase(t)
But
Programming by Contract
Spell out responsibilities
o of caller
o ofimplementor
Increase reliability
Increase efficiency
Preconditions
Caller attempts to remove message from empty MessageQueue
What should happen?
MessageQueue can declare this as an error
MessageQueue can tolerate call and return dummy value
What is better?
Preconditions
Excessive error checking is costly
Returning dummy values can complicate testing
Contract metaphor
o Service provider must specify preconditions
o If precondition is fulfilled, service provider must work correctly
57
o Otherwise, service provider can do anything
When precondition fails, service provider may
o throw exception
o return false answer
o corrupt data
Preconditions
/**
Remove message at head
@return the message at the head
@precondition size() > 0
*/
Message removeFirst()
{
return (Message)elements.remove(0);
}
A Circular Array
58
Wrapping around the End
Preconditions
In circular array implementation, failure of remove precondition corrupts queue!
Bounded queue needs precondition for add
Naive approach:
@precondition size() < elements.length
Precondition should be checkable by caller
Better:
@precondition size() < getCapacity()
Assertions
Mechanism for warning programmers
Can be turned off after testing
Useful for warning programmers about precondition failure
Syntax:
assert condition;
assert condition : explanation;
Assertions
59
public Message removeFirst()
{
assert count > 0 : "violated precondition size() > 0";
Message r = elements[head];
. . .
}
Postconditions
Conditions that the service provider guarantees
Every method promises description, @return
Sometimes, can assert additional useful condition
Example: add method
q.add(m1);
m2 = q.remove();
Class Invariants
Condition that is
o true after every constructor
60
o preserved by every method
(if it's true before the call, it's again true afterwards)
Useful for checking validity of operations
Class Invariants
Example: Circular array queue
return elements[head];
Class Invariants
Example: Queue with array list
elements only contains objects of type Message
Ch2/mail/MessageQueue.java
It's true for constructor.
elements is initially empty
Check mutators. Start with add
Parameter type is Message
What's the use? Casts are correct!
return (Message)elements.remove(0);
Unit Testing
Unit test = test of a single class
Design test cases during implementation
Run tests after every implementation change
When you find a bug, add a test case that catches it
JUnit
61
JUnit
Test class name = tested class name + Test
Test methods start with test
import junit.framework.*;
public class DayTest extends TestCase
{
public void testAdd() { ... }
public void testDaysBetween() { ... }
. . .
}
JUnit
Each test case ends with assertion
Test framework catches assertion failures
62
Object-Oriented Design & Patterns
Cay S. Horstmann
Chapter 4
Chapter Topics
Displaying an Image
Polymorphism
Drawing Shapes
The Comparable Interface
The Comparator Interface
Anonymous Classes
Frames and User Interface Components
User Interface Actions
Timers
Designing an Interface
Displaying an Image
Use JOptionPane to display message:
63
JOptionPane.showMessageDialog(null, "Hello, World!");
Displaying an Image
Can specify arbitrary image file
JOptionPane.showMessageDialog(
null,
"Hello, World!",
"Message",
JOptionPane.INFORMATION_MESSAGE,
new ImageIcon("globe.gif"));
Displaying an Image
What if we don't want to generate an image file?
Fortunately, can use any class that implements Icon interface type
ImageIcon is one such class
Easy to supply your own class
64
The Icon Interface Type
public interface Icon
{
int getIconWidth();
int getIconHeight();
void paintIcon(Component c, Graphics g, int x, int y)
}
Interface Types
No implementation
Implementing class must supply implementation of all methods
Ch4/icon2/MarsIcon.java
showMessageDialog expects Icon object
Ok to pass MarsIcon
Ch4/icon2/IconTest.java
Polymorphism
public static void showMessageDialog(...Icon anIcon)
65
showMessageDialog shows
o icon
o message
o OK button
showMessageDialog must compute size of dialog
width = icon width + message size + blank size
How do we know the icon width?
Polymorphism
showMessageDialog doesn't know which icon is passed
o ImageIcon?
o MarsIcon?
o . . .?
The actual type of anIcon is not Icon
There are no objects of type Icon
anIcon belongs to a class that implements Icon
That class defines a getIconWidth method
Polymorphism
Which getIconWidth method is called?
Could be
o MarsIcon.getIconWidth
o ImageIcon.getIconWidth
o ...
Depends on object to which anIcon reference points, e.g.
66
Benefits of Polymorphism
Loose coupling
o showMessageDialog decoupled from ImageIcon
o Doesn't need to know about image processing
Extensibility
o Client can supply new icon types
Drawing Shapes
paintIcon method receives graphics context of type Graphics
Actually a Graphics2D object in modern Java versions
Shape s = . . .;
g2.draw(s);
Drawing Ellipses
67
Drawing Line Segments
Point2D.Double is a point in the plane
Line2D.Double joins to points
Drawing Text
68
g2.drawString(text, x, y);
x, y are base point coordinates
Filling Shapes
Fill interior of shape
g2.fill(shape);
ArrayList a = . . .
Collections.sort(a);
object1.compareTo(object2) returns
o Negative number if object1 less than object2
o 0 if objects identical
69
o Positive number if object1 greater than object2
Collections.sort(list, comp);
Anonymous Classes
No need to name objects that are used only once
Collections.sort(countries,
new CountryComparatorByName());
70
{
public int compare(Object obj1, Object obj2)
{
Country country1 = (Country)obj1;
Country country2 = (Country)obj2;
return country1.getName().compareTo(country2.getName());
}
};
Anonymous Classes
anonymous new expression:
o defines anonymous class that implements Comparator
o defines compare method of that class
o constructs one object of that class
Cryptic syntax for very useful feature
Anonymous Classes
Commonly used in factory methods:
public static Comparator comparatorByName()
{
return new Comparator()
{
public int compare(Object o1, Object o2) { . . .
}
};
}
Collections.sort(a, Country.comparatorByName());
Neat arrangement if multiple comparators make sense
(by name, by area, ...)
Frames
Frame window has decorations
o title bar
o close box
o provided by windowing system
JFrame frame = new JFrame();
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.show();
Adding Components
Construct components
71
JButton helloButton = new JButton("Say Hello");
contentPane.add(helloButton);
Ch4/frame/FrameTest.java
helloButton.addActionListener(new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
textField.setText("Hello, World");
}
});
72
Remarkable: Inner class can access variables from enclosing scope
e.g. textField
Can access enclosing instance fields, local variables
Local variables must be marked final
final JTextField textField = ...;
helloButton.addActionListener(listener);
listener.actionPerformed(event);
textField.setText("Hello, World!");
Ch4/action1/ActionTest.java
Timers
Supply delay, action listener
ActionListener listener = ...;
final int DELAY = 1000; // 1000 millisec = 1 sec
73
Timer t = new Timer(DELAY, listener);
t.start();
Action listener called when delay elapsed
Ch4/timer/TimerTest.java
74
public interface MoveableShape
{
void draw(Graphics2D g2);
void translate(int dx, int dy);
}
CarShape class implements MoveableShape
public class CarShape implements MoveableShape
{
public void translate(int dx, int dy)
{ x += dx; y += dy; }
. . .
}
75
76
Object-Oriented Design & Patterns
Cay S. Horstmann
Chapter 5
Chapter Topics
Iterators
The Pattern Concept
The OBSERVER Pattern
Layout Managers and the STRATEGY Pattern
Components, Containers, and the COMPOSITE Pattern
Scroll Bars and the DECORATOR Pattern
How to Recognize Patterns
Putting Patterns to Work
List Iterators
LinkedList list = . . .;
ListIterator iterator = list.listIterator();
while (iterator.hasNext())
{
77
Object current = iterator.next();
. . .
}
Why iterators?
Exposes implementation
Error-prone
List
???
78
for (list.reset(); list.hasNext(); list.next())
{
Object x = list.get();
. . .
}
79
Short Passages Pattern
Context
"...Long, sterile corridors set the scene for everything bad about modern architecture..."
Problem
a depressing picture
issues of light and furniture
research about patient anxiety in hospitals
research that suggests that corridors over 50 ft are considered uncomfortable
Keep passages short. Make them as much like rooms as possible, with carpets or wood on
the floor, furniture, bookshelves, beautiful windows. Make them generous in shape and
always give them plenty of light; the best corridors and passages of all are those which
have windows along an entire wall.
80
Iterator Pattern
Context
Iterator Pattern
Solution
Iterator Pattern
81
Iterator Pattern
Names in pattern are examples
Names differ in each occurrence of pattern
Model/View/Controller
Some programs have multiple editable views
Example: HTML Editor
o WYSIWYG view
o structure view
o source view
Editing one view updates the other
Updates seem instantaneous
82
Model/View/Controller
Model/View/Controller
Model: data structure, no visual representation
Views: visual representations
Controllers: user interaction
Model/View/Controller
Views/controllers update model
Model tells views that data has changed
Views redraw themselves
Model/View/Controller
83
Observer Pattern
Model notifies views when something interesting happens
Button notifies action listeners when something interesting happens
Views attach themselves to model in order to be notified
Action listeners attach themselves to button in order to be notified
Generalize: Observers attach themselves to subject
Observer Pattern
Context
Solution
Observer Pattern
84
Names in Observer Pattern
Name in Design Pattern Actual Name (Swing buttons)
Subject JButton
Observer ActionListener
notify() actionPerformed()
Layout Managers
User interfaces made up of components
Components placed in containers
Container needs to arrange components
Swing doesn't use hard-coded pixel coordinates
Advantages:
o Can switch "look and feel"
o Can internationalize strings
Layout manager controls arrangement
Layout Managers
FlowLayout: left to right, start new row when full
BoxLayout: left to right or top to bottom
BorderLayout: 5 areas, Center, North, South, East, West
GridLayout: grid, all components have same size
GridBagLayout: complex, like HTML table
85
Layout Managers
Layout Managers
Set layout manager
JPanel keyPanel = new JPanel();
keyPanel.setLayout(new GridLayout(4, 3));
Add components
for (int i = 0; i < 12; i++)
keyPanel.add(button[i]);
Layout Managers
86
Voice Mail System GUI
Same backend as text-based system
Only Telephone class changes
Buttons for keypad
Text areas for microphone, speaker
87
88
Voice Mail System GUI
Arrange keys in panel with GridLayout:
89
keyButton.addActionListener(...);
}
90
Custom Layout Manager
Form layout
Odd-numbered components right aligned
Even-numbered components left aligned
Implement LayoutManager interface type
91
Dimension minimumLayoutSize(Container parent);
Dimension preferredLayoutSize(Container parent);
void addLayoutComponent(String name, Component comp);
void removeLayoutComponent(Component comp);
}
Form Layout
Ch5/layout/FormLayout.java
Ch5/layout/FormLayoutTest.java
Note: Can use GridBagLayout to achieve the same effect
Strategy Pattern
Pluggable strategy for layout management
Layout manager object responsible for executing concrete strategy
Generalizes to Strategy Design Pattern
Other manifestation: Comparators
Strategy Pattern
Context
Solution
Strategy Pattern
92
Strategy Pattern: Layout Management
Name in Design Pattern Actual Name (layout management)
Context Container
Strategy LayoutManager
ConcreteStrategy a layout manager such as BorderLayout
doWork() a method such as layoutContainer
93
Composite Pattern
Context
Solution
Composite Pattern
Composite Pattern
Name in Design Pattern Actual Name (AWT components)
Primitive Component
Composite Container
Leaf a component without children (e.g. JButton)
method() a method of Component (e.g. getPreferredSize)
Scroll Bars
Scroll bars can be attached to components
Approach #1: Component class can turn on scroll bars
94
Approach #2: Scroll bars can surround component
Scroll Bars
Decorator Pattern
Context
Decorator Pattern
Solution
95
2. Concrete component classes realize this interface type.
3. Decorator classes also realize this interface type.
4. A decorator object manages the component object that it decorates
5. When implementing a method from the component interface type, the decorator
class applies the method to the decorated component and combines the result with
the effect of the decoration.
Decorator Pattern
Streams
InputStreamReader reader = new InputStreamReader(System.in);
BufferedReader console = new BufferedReader(reader);
96
Decorator BufferedReader
method() read
Litmus Test
Can add border to Swing component
Undeniably decorative
Is it an example of DECORATOR?
Litmus Test
1. Component objects can be decorated (visually or behaviorally enhanced)
PASS
2. The decorated object can be used in the same way as the undecorated object
PASS
3. The component class does not want to take on the responsibility of the decoration
FAIL--the component class has setBorder method
4. There may be an open-ended set of possible decorations
97
Interface type LineItem:
Ch5/invoice/LineItem.java
Product is a concrete class that implements this interface:
Ch5/invoice/Product.java
Bundles
Bundle = set of related items with description+price
E.g. stereo system with tuner, amplifier, CD player + speakers
A bundle has line items
A bundle is a line item
COMPOSITE pattern
Ch5/invoice/Bundle.java (look at getPrice)
Bundles
Discounted Items
Store may give discount for an item
Discounted item is again an item
DECORATOR pattern
Ch5/invoice/DiscountedItem.java (look at getPrice)
Alternative design: add discount to LineItem
Discounted Items
98
Model/View Separation
GUI has commands to add items to invoice
GUI displays invoice
Decouple input from display
Display wants to know when invoice is modified
Display doesn't care which command modified invoice
OBSERVER pattern
Change Listeners
Use standard ChangeListener interface type
public interface ChangeListener
{
void stateChanged(ChangeEvent event);
}
Invoice collects ArrayList of change listeners
When the invoice changes, it notifies all listeners:
ChangeEvent event = new ChangeEvent(this);
for (int i = 0; i < listeners.size(); i++)
{
ChangeListener listener =
(ChangeListener)listeners.get(i);
listener.stateChanged(event);
}
Change Listeners
Display adds itself as a change listener to the invoice
Display updates itself when invoice object changes state
99
final Invoice invoice = new Invoice();
final JTextArea textArea = new JTextArea(20, 40);
ChangeListener listener = new
ChangeListener()
{
public void stateChanged(ChangeEvent event)
{
textArea.setText(...);
}
};
Iterators
Use standard Iterator interface type
public interface Iterator
{
boolean hasNext();
Object next();
void remove();
}
100
remove is "optional operation" (see ch. 8)
implement to throw UnsupportedException
implement hasNext/next manually to show inner workings
Ch5/invoice/Invoice.java
Iterators
Formatting Invoices
Simple format: dump into text area
May not be good enough,
E.g. HTML tags for display in browser
Want to allow for multiple formatting algorithms
STRATEGY pattern
Formatting Invoices
ch5/invoice/InvoiceFormatter.java
ch5/invoice/SimpleFormatter.java
ch5/invoice/InvoiceTest.java
Formatting Invoices
101
Formatting Invoices
102
Object-Oriented Design & Patterns
Cay S. Horstmann
Chapter 6
Chapter Topics
The Concept of Inheritance
Graphics Programming with Inheritance
Abstract Classes
The TEMPLATE METHOD Pattern
Protected Interfaces
The Hierarchy of Swing Components
The Hierarchy of Standard Geometrical Shapes
The Hierarchy of Exception Classes
When Not to Use Inheritance
Modeling Specialization
Start with simple Employee class
public class Employee
103
{
public Employee(String aName) { name = aName; }
public void setSalary(double aSalary) { salary =
aSalary; }
public String getName() { return name; }
public double getSalary() { return salary; }
Modeling Specialization
Manager class adds new method: setBonus
Manager class overrides existing method: getSalary
Adds salary and bonus
public class Manager extends Employee
{
public Manager(String aName) { ... }
public void setBonus(double aBonus) { bonus =
aBonus; } // new method
public double getSalary() { ... } // overrides
Employee method
Modeling Specialization
104
Manager Methods and Fields
methods setSalary, getname (inherited from Employee)
method getSalary (overridden in Manager)
method setBonus (defined in Manager)
fields name and salary (defined in Employee)
field bonus (defined in Manager)
105
Inheritance Hierarchies
Real world: Hierarchies describe general/specific relationships
o General concept at root of tree
o More specific concepts are children
Programming: Inheritance hierarchy
o General superclass at root of tree
o More specific subclasses are children
Inheritance Hierarchies
106
Example:
Employee e;
...
System.out.println("salary=" + e.getSalary());
Can set e to Manager reference
Polymorphism: Correct getSalary method is invoked
107
If subclass constructor doesn't call super, superclass must have constructor
without parameters
Preconditions
Precondition of redefined method at most as strong
public class Employee
{
/**
Sets the employee salary to a given value.
@param aSalary the new salary
@precondition aSalary > 0
*/
public void setSalary(double aSalary) { ... }
}
Can we redefine Manager.setSalary with precondition
salary > 100000?
No--Could be defeated:
108
Overriding paintComponent
Draw a car:
public class MyPanel extends JPanel
{
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;
car.draw(g2);
}
...
}
Problem: Screen is corrupted when moving frame
Remedy: call super.paintComponent(g)
Overriding paintComponent
Mouse Listeners
Attach mouse listener to component
Can listen to mouse events (clicks) or mouse motion events
109
public interface MouseMotionListener
{
void mouseMoved(MouseEvent event);
void mouseDragged(MouseEvent event);
}
Mouse Adapters
What if you just want to listen to mousePressed?
Extend MouseAdapter
addMouseListener(new
MouseAdapter()
{
public void mousePressed(MouseEvent event)
{
mouse action goes here
}
});
110
Scene Editor
Draws various shapes
User can add, delete, move shapes
User selects shape with mouse
Selected shape is highlighted (filled in)
Scene Editor
111
The SceneShape Interface Type
Abstract Classes
112
Factor out common behavior
(setSelected, isSelected)
Subclasses inherit common behavior
Some methods still undefined
(draw, drawSelection, translate, contains)
Abstract Classes
Abstract Classes
SelectableShape doesn't define all SceneShape methods
It's abstract
public abstract class SelectableShape implements SceneShape
HouseShape and CarShape are concrete
Can't instantiate abstract class:
113
Ok to have variables of abstract class type:
Scene Editor
Mouse listener selects/unselects item
Mouse motion listener drags item
Remove button removes selected items
Ch6/scene1/ScenePanel.java
Ch6/scene1/SceneEditor.java
Ch6/scene1/HouseShape.java
114
Template Method
drawSelection calls draw
Must declare draw in SelectableShape
No implementation at that level!
Declare as abstract method
public abstract void draw(Graphics2D g2)
Defined in CarShape, HouseShape
drawSelection method calls draw, translate
drawSelection doesn't know which methods--polymorphism
drawSelection is a template method
Ch6/scene2/SelectableShape.java
Ch6/scene2/HouseShape.java
1. Define a superclass that has a method for the algorithm and abstract methods for
the primitive operations.
115
2. Implement the algorithm to call the primitive operations in the appropriate order.
3. Do not define the primitive operations in the superclass, or define them to have
appropriate default behavior.
4. Each subclass defines the primitive operations but not the algorithm.
Compound Shapes
GeneralPath: sequence of shapes
116
Compound Shapes
public HouseShape()
{
add(new Rectangle(...));
add(new Triangle(...));
}
117
Protected Access
Make CompoundShape.add method protected
Protects HouseShape: other classes can't add graffiti
Protected features can be accessed by subclass methods...
...and by methods in the same package
Bad idea to make fields protected
protected GeneralPath path; // DON'T
Ok to make methods protected
protected void add(Shape s) // GOOD
Protected interface separate from public interface
int getWidth()
int getHeight()
Dimension getPreferredSize()
void setBackground(Color c)
. . .
118
Hierarchy of Swing Components
History: First came AWT, Abstract Window Toolkit
Used native components
Subtle platform inconsistencies
Write once, run anywhere ->
Write once, debug everywhere
Swing paints components onto blank windows
Supports multiple look and feel implementations
Point
Rectangle
Polygon
119
Java 2: sophisticated shapes, floating-point coordinates
Point2D
Rectangle2D
RoundRectangle2D
Line2D
Ellipse2D
Arc2D
QuadCurve2D
CubicCurve2D
GeneralPath
Area
Rectangular Shapes
Subclasses of RectangularShape:
Rectangle2D
RoundRectangle2D
Ellipse2D
Arc2D
getCenterX/getCenterY
getMinX/getMinY
getMaxX/getMaxY
120
getWidth/getHeight
setFrameFromCenter/setFrameFromDiagonal
Float/Double Classes
Each class has two subclasses, e.g.
Rectangle2D.Double
Rectangle2D.Float
Float/Double Classes
Float/Double Classes
public class Rectangle2D
{
public static class Float extends Rectangle2D
{
public double getX() { return x; }
public double getY() { return y; }
public double getWidth() { return width; }
public double getHeight() { return height;}
public void setRect(float x, float y, float w, float h)
{
this.x = x; this.y = y;
this.width = w; this.height = h;
}
public void setRect(double x, double y,
double w, double h)
{
121
this.x = (float)x; this.y = (float)y;
this.width = (float)w; this.height = (float)h;
}
...
public float x;
public float y;
public float width;
public float height;
}
. . .
Float/Double Classes
. . .
public static class Double extends Rectangle2D
public double getX() { return x; }
public double getY() { return y; }
public double getWidth() { return width; }
public double getHeight() { return height;}
public void setRect(double x, double y,
double w, double h)
{
this.x = x; this.y = y;
this.width = w; this.height = h;
}
...
public double x;
public double y;
public double width;
public double height;
}
...
}
Float/Double Classes
Rectangle2D class has no instance variables
Template Method Pattern at work:
122
TEMPLATE METHOD Pattern
Name in Design Pattern Actual Name (Rectangles)
AbstractClass Rectangle
ConcreteClass Rectangle2D.Double
templateMethod() contains
primitiveOpn() getX, getY, getWidth, getHeight
123
Catching Exceptions
Can have multiple catch clauses:
try
{
code that may throw exceptions
}
catch (ExceptionType1 exception1)
{
handler for ExceptionType1
}
catch (ExceptionType2 exception1)
{
handler for ExceptionType2
}
. . .
124
public class Circle extends Point // DON'T
{
public Circle(Point center, int radius) { ... }
public void draw(Graphics g) { ... }
private int radius;
}
125
Remedy: Use aggregation
126
Object-Oriented Design & Patterns
Cay S. Horstmann
Chapter 7
Chapter Topics
The Java Type System
Type Inquiry
The Object Class
Shallow and Deep Copy
Serialization
Reflection
The Java Beans Component Model
Types
Type: set of values and the operations that can be applied to the values
Strongly typed language: compiler and run-time system check that no operation
can execute that violates type system rules
127
Compile-time check
Employee e = new Employee();
e.clear(); // ERROR
Run-time check:
e = null;
e.setSalary(20000); // ERROR
Java Types
Primitive types:
int short long byte
char float double boolean
Class types
Interface types
Array types
The null type
Note: void is not a type
Java Values
value of primitive type
reference to object of class type
reference to array
null
Note: Can't have value of interface type
Subtype Relationship
S is a subtype of T if
128
S and T are the same type
S and T are both class types, and T is a direct or indirect superclass of S
S is a class type, T is an interface type, and S or one of its superclasses
implements T
S and T are both interface types, and T is a direct or indirect superinterface of S
S and T are both array types, and the component type of S is a subtype of the
component type of T
S is not a primitive type and T is the type Object
S is an array type and T is Cloneable or Serializable
S is the null type and T is not a primitive type
Subtype Examples
Container is a subtype of Component
JButton is a subtype of Component
FlowLayout is a subtype of LayoutManager
ListIterator is a subtype of Iterator
Rectangle[] is a subtype of Shape[]
int[] is a subtype of Object
int is not a subtype of long
long is not a subtype of int
int[] is not a subtype of Object[]
Subtype Examples
129
The ArrayStoreException
Rectangle[] is a subtype of Shape[]
Can assign Rectangle[] value to Shape[] variable:
Array References
130
Wrapper Classes
Primitive types aren't classes
Use wrappers when objects are expected
Wrapper for each type:
Example: ArrayList
Enumerated Types
Finite set of values
Example: { SMALL, MEDIUM, LARGE }
Java has no syntax for enumerated types
Can fake them with integer constants
public static final int SMALL = 1;
public static final int MEDIUM = 2;
public static final int LARGE = 3;
Not typesafe
int size = LARGE;
size++;
Typesafe Enumerations
131
Class with fixed number of instances
public class Size
{
private Size(String name) { this.name = name; }
private String name;
public static final Size SMALL = new Size("SMALL");
public static final Size MEDIUM = new
Size("MEDIUM");
public static final Size LARGE = new Size("LARGE");
}
Private constructor!
String field not necessary (but convenient for toString, serialization)
Typical use:
Size imageSize = Size.MEDIUM;
if (imageSize == Size.SMALL) . . .
Type Inquiry
Test whether e is a Shape:
if (e instanceof Shape) . . .
Common before casts:
Shape s = (Shape) e;
Don't know exact type of e
Could be any class implementing Shape
If e is null, test returns false (no exception)
132
Type Inquiry
Test whether e is a Rectangle:
if (e.getClass() == Rectangle.class) . . .
Ok to use ==
A unique Class object for every class
Test fails for subclasses
Use instanceof to test for subtypes:
if (x instanceof Rectangle) . . .
Array Types
Can apply getClass to an array
Returned object describes an array type
[D for double[])
[[java.lang.String; for String[][]
133
All classes extend Object
Most useful methods:
o String toString()
o boolean equals(Object otherObject)
o Object clone()
o int hashCode()
Typical string:
Employee[name=Harry Hacker,salary=35000]
134
{
return super.toString()
+ "[department=" + department + "]";
}
...
}
Typical string
Manager[name=Dolly Dollar,salary=100000][department=Finance]
/**
Searches for the first occurrence of the given argument,
testing for equality using the equals method.
@param elem an object.
@return the index of the first occurrence
of the argument in this list; returns -1 if
the object is not found.
*/
public int indexOf(Object elem)
{
if (elem == null)
{
for (int i = 0; i < size; i++)
if (elementData[i] == null) return i;
}
else
{
for (int i = 0; i < size; i++)
if (elem.equals(elementData[i])) return i;
}
return -1;
}
135
// not complete--see below
{
Employee other = (Employee)otherObject;
return name.equals(other.name)
&& salary == other.salary;
}
...
}
The Object.equalsMethod
Object.equals tests for identity:
136
Override equals if you don't want to inherit that behavior
Fixing Employee.equals
Violates two rules
Add test for null:
if (otherObject == null) return false
What happens if otherObject not an Employee
Should return false (because of symmetry)
Common error: use of instanceof
if (!(otherObject instanceof Employee)) return false;
// don't do this for non-final classes
Violates symmetry: Suppose e, m have same name, salary
e.equals(m) is true (because m instanceof Employee)
m.equals(e) is false (because e isn't an instance of Manager)
Remedy: Test for class equality
if (getClass() != otherObject.getClass()) return false;
Hashing
hashCode method used in HashMap, HashSet
Computes an int from an object
Example: hash code of String
int h = 0;
137
for (int i = 0; i < s.length(); i++)
h = 31 * h + s.charAt(i);
Hash code of "eat" is 100184
Hash code of "tea" is 114704
Hashing
Must be compatible with equals:
if x.equals(y), then x.hashCode() == y.hashCode()
Object.hashCode hashes memory address
NOT compatible with redefined equals
Remedy: Hash all fields and combine codes:
Cloning
138
Cloning
Object.clone makes new object and copies all fields
Cloning is subtle
Object.clone is protected
Subclass must redefine clone to be public
139
Shallow Cloning
clone makes a shallow copy
Instance fields aren't cloned
Deep Cloning
Why doesn't clone make a deep copy?
Wouldn't work for cyclic data structures
Not a problem for immutable fields
You must clone mutable fields
Deep Cloning
140
Cloning and Inheritance
Object.clone is paranoid
o clone is protected
o clone only clones Cloneable objects
o clone throws checked exception
You don't have that luxury
Manager.clone must be defined if Manager adds mutable fields
Rule of thumb: if you extend a class that defines clone, redefine clone
Lesson to learn: Tagging interfaces are inherited. Use them only to tag properties
that inherit
Serialization
Save collection of objects to stream
Construct ObjectOutputStream:
ObjectOutputStream out
= new ObjectOutputStream(
new FileOutputStream("staff.dat"));
141
Save the array and close the stream
out.writeObject(staff);
out.close();
Serialization
The array and all of its objects and their dependent objects are saved
Employee doesn't have to define any method
Needs to implement the Serializable interface
Another tagging interface with no methods
142
Supply private (!) methods
private void writeObject(ObjectOutputStream out)
private void readObject(ObjectInputStream in)
In these methods
o Call writeDefaultObject/readDefaultObject
o Manually save other data
Ch7/serial/Car.java
Reflection
Ability of running program to find out about its objects and classes
Class object reveals
o superclass
o interfaces
o package
o names and types of fields
o names, parameter types, return types of methods
o parameter types of constructors
Reflection
Class getSuperclass()
Class[] getInterfaces()
Package getPackage()
Field[] getDeclaredFields()
Constructor[] getDeclaredConstructors()
Method[] getDeclaredMethods()
Enumerating Fields
Print the names of all static fields of the Math class:
Enumerating Constructors
Print the names and parameter types of all Rectangle
constructors:
143
for (int j = 0; j < params.length; j++)
{
if (j > 0) System.out.print(", ");
System.out.print(params[j].getName());
}
System.out.println(")");
}
Yields
Rectangle()
Rectangle(java.awt.Rectangle)
Rectangle(int, int, int, int)
Rectangle(int, int)
Rectangle(java.awt.Point, java.awt.Dimension)
Rectangle(java.awt.Point)
Rectangle(java.awt.Dimension)
Method m = Rectangle.class.getDeclaredMethod(
"contains",
new Class[] { int.class, int.class });
Constructor c = Rectangle.class.getDeclaredConstructor(
new Class[] {});
Invoking a Method
Supply implicit parameter (null for static methods)
Supply array of explicit parameter values
Wrap primitive types
Unwrap primitive return value
Example: Call System.out.println("Hello, World") the hard way.
Method m = PrintStream.class.getDeclaredMethod(
"println",
new Class[] { String.class } );
m.invoke(System.out,
new Object[] { "Hello, World!" });
Inspecting Objects
144
Can obtain object contents at runtime
Useful for generic debugging tools
Need to gain access to private fields
Class c = obj.getClass();
Field f = c.getDeclaredField(name);
f.setAccessible(true);
Inspecting Objects
Example: Peek inside string tokenizer
Ch7/code/reflect2/FieldTest.java
Output
int currentPosition=0
int newPosition=-1
int maxPosition=13
java.lang.String str=Hello, World!
java.lang.String delimiters=,
boolean retDelims=false
boolean delimsChanged=false
char maxDelimChar=,
---
int currentPosition=5
. . .
Components
More functionality than a single class
Reuse and customize in multiple contexts
145
"Plug components together" to form applications
Successful model: Visual Basic controls
o calendar
o graph
o database
o link to robot or instrument
Componens composed into program inside builder environment
A Builder Environment
Java Beans
Java component model
Bean has
o methods (just like classes)
o properties
o events
Java Beans
146
A Calendar Bean
A Property Sheet
Edit properties with property sheet
Facade Class
Bean usually composed of multiple classes
One class nominated as facade class
147
Clients use only facade class methods
Facade Pattern
Context
Solution
1. Define a facade class that exposes all capabilities of the subsystem as methods
2. The facade methods delegate requests to the subsystem classes
3. The subsystem classes do not know about the facade class
Facade Pattern
Facade Pattern
Name in Design Pattern Actual Name (Beans)
148
Client Builder tool
Facade Main bean class with which the tool interacts
SubsystemClass Class used to implement bean functionality
Bean Properties
Property = value that you can get and/or set
Most properties are get-and-set
Can also have get-only and set-only
Property not the same as instance field
Setter can set fields, then call repaint
Getter can query database
Property Syntax
Not Java :-(
C#, JavaScript, Visual Basic
b.propertyName = value
calls setter
variable = b.propertyName
calls getter
149
Editing Beans in a Builder Tool
Add button to frame
Edit button with property sheet
150
Packaging a Bean
Compile bean classes
Ch7/carbean1/CarBean.java
Create manifest file
Ch7/carbean1/CarBean.mf
Run JAR tool:
jar cvfm CarBean.jar CarBean.mf *.class
Import JAR file into builder environment
Composing Beans
Make new frame
Add car bean, slider to frame
Edit stateChanged event of slider
Add handler code
carBean1.setX(jSlider1.getValue());
Compile and run
Move slider: the car moves
151
Composing Beans
Bean Information
Builder environment loads beans
Looks for get/set methods in facade class
Can discover spurious properties
JButton: Object getTreeLock()
Alternate mechanism: BeanInfo class
Must have name FacadeClassNameBeanInfo
E.g. HouseBeanBeanInfo
152
int getDefaultEventIndex()
int getDefaultPropertyIndex()
BeanInfo[] getAdditionalBeanInfo()
Property Editors
Property sheet enumerates properties
Allows user to edit property values
How can one edit values of arbitrary types?
Built-in editors for String, Color, etc
Supply custom editor for your own types
153
Property sheet uses text field
PropertyEditorManager.registerEditor(valueClass, editorClass)
Per-bean setting
In bean info class:
Example: CarBean
Ch7/carbean2/CarBean.java
Ch7/carbean2/CarBeanBeanInfo.java
Ch7/carbean2/DimensionEditor.java
Ch7/carbean2/DrawMode.java
Ch7/carbean2/DrawModeEditor.java
Ch7/carbean2/CustomColorEditor.java
Example: CarBean
154
Implementing a Property Sheet
Used for graph framework in chapter 8
Form shows property names on left, editors on right
155
Object-Oriented Design & Patterns
Cay S. Horstmann
Chapter 8
Frameworks
Chapter Topics
Frameworks
Applets as a simple framework
The collections framework
A graph editor framework
Enhancing the graph editor framework
Frameworks
Set of cooperating classes
Structures the essential mechanisms of a problem domain
Example: Swing is a GUI framework
Framework != design pattern
Typical framework uses multiple design patterns
Application Frameworks
156
Implements services common to a type of applications
Programmer forms subclasses of framework classes
Result is an application
Inversion of control: framework controls execution flow
Applets
Applet: Java program that runs in a web browser
Programmer forms subclass of Applet or JApplet
Overwrites
init/destroy
start/stop
paint
Applets
Applets
Interacts with ambient browser
getParameter
showDocument
HTML page contains applet tag and parameters
157
<param name="delay" value="10"/>
</applet>
Example Applet
Shows scrolling banner
init reads parameters
start/stop start and stop timer
paint paints the applet surface
Ch8/applet/BannerApplet.java
Example Applet
Applets as a Framework
Applet programmer uses inheritance
Applet class deals with generic behavior (browser interaction)
Inversion of control: applet calls init, start,stop,destroy
Collections Framework
Java library supplies standard data structures
Supplies useful services (e.g. Collections.sort, Collections.shuffle)
Framework: Programmers can supply additional data structures, services
New data structures automatically work with services
New services automatically work with data structures
158
Collection: the most general collection interface type
Set: an unordered collection that does not permit duplicate elements
SortedSet: a set whose elements are visited in sorted order
List: an ordered collection
Collections Framework
159
Iterator Interface Type
Iterator traverses elements of collection
boolean hasNext()
Object next()
void remove()
AbstractCollection Class
Collection is a hefty interface
Convenient for clients, inconvenientfor implementors
Many methods can be implemented from others (Template method!)
Example: toArray
result[i] = e.next();
return result;
}
AbstractCollection Class
Can't place template methods in interface
Place them in AbstractCollection class
AbstractCollection convenient superclass for implementors
Only two methods undefined: size,iterator
160
Sets
Set interface adds no methods to Collection!
Conceptually, sets are a subtype of collections
Sets don't store duplicates of the same element
Sets are unordered
Separate interface: an algorithm can require a Set
Lists
Lists are ordered
Each list position can be accessed by an integer index
Subtype methods:
List Iterators
Indexing
Bidirectional behavior
Subtype methods:
161
int nextIndex()
int previousIndex()
boolean hasPrevious()
Object previous()
void set(Object obj)
List Classes
ArrayList
LinkedList
Indexed access of linked list elements is possible, but slow
Weakness in the design
Partial fix in Java 1.4: RandomAccess interface
List Classes
Optional Operations
Many operations tagged as "optional"
Example: Collection.add, Collection.remove
Default implementation throws exception
Why have optional operations?
Views
View = collection that shows objects that are stored elsewhere
Example: Arrays.asList
String[] strings = { "Kenya", "Thailand", "Portugal" };
List view = Arrays.asList(strings)
162
Does not copy elements!
Can use view for common services
otherList.addAll(view);
Views
get/set are defined to access underlying array
Arrays.asList view has no add/remove operations
Can't grow/shrink underlying array
Several kinds of views:
read-only
modifyable
resizable
...
Optional operations avoid inflation of interfaces
Controversial design decision
User Interface
Toolbar on top
Grabber button for selecting nodes/edges
Buttons for current node/edge type
Menu
Drawing area
163
User Interface
Mouse Operations
Click on empty space: current node inserted
Click on node or edge: select it
Drag node when current tool an edge: connect nodes
Drag node when current tool not an edge: move node
Division of Responsibility
Divide code between
o framework
o specific application
Rendering is app specific (e.g. transistor)
Hit testing is app specific (odd node shapes)
Framework draws toolbar
Framework does mouse listening
164
Adding Nodes and Edges
Objects are more flexible than classes
new CircleNode(Color.BLACK)
new CircleNode(Color.WHITE)
When user inserts new node, the toolbar node is cloned
Node prototype = node of currently selected toolbar button;
Node newNode = (Node) prototype.clone();
Point2D mousePoint = current mouse position;
graph.add(newNode, mousePoint);
Example of PROTOTYPE pattern
PROTOTYPE Pattern
Context
1. A system instantiates objects of classes that are not known when the system is
built.
2. You do not want to require a separate class for each kind of object.
3. You want to avoid a separate hierarchy of classes whose responsibility it is to
create the objects.
Solution
PROTOTYPE Pattern
PROTOTYPE Pattern
165
Name in Design Pattern Actual name (graph editor)
Prototype Node
ConcretePrototype1 CircleNode
Creator The GraphPanel that handles the mouse operation for
adding new nodes
Framework Classes
Framework programmer implements Node/Edge interfaces
draw draws node/edge
getBounds returns enclosing rectangle (to compute total graph size for
scrolling)
Edge.getStart, getEnd yield start/end nodes
Node.getConnectionPoint computes attachment point on shape boundary
Edge.getConnectionPoints yields start/end coordinates (for grabbers)
clone overridden to be public
Framework Classes
AbstractEdge class for convenience
Programmer implements Node/Edge type or extends AbstractEdge
Ch8/graphed/Node.java
Ch8/graphed/Edge.java
Ch8/graphed/AbstractEdge.java
166
Framework Classes
Graph collects nodes and edges
Subclasses override methods
public abstract Node[] getNodePrototypes()
public abstract Edge[] getEdgePrototypes()
Ch8/graphed/Graph.java
Framework UI Classes
GraphFrame: a frame that manages the toolbar, the menu bar, and the graph
panel.
ToolBar: a panel that holds toggle buttons for the node and edge icons.
GraphPanel: a panel that shows the graph and handles the mouse clicks and
drags for the editing commands.
Application programmers need not subclass these classes
A Framework Instance
Simple application
Draw black and white nodes
Join nodes with straight lines
Programmer responsibilities
For each node and edge type, define a class that implements the Node or Edge
interface type
Supply all required methods, such as drawing and containment testing.
Define a subclass of the Graph class and supply getNodePrototypes,
getEdgePrototypes
Supply a class with a main method
A Framework Instance
167
A Framework Instance
Ch8/graphed/SimpleGraph.java
Ch8/graphed/SimpleGraphEditor.java
Ch8/graphed/CircleNode.java
Ch8/graphed/LineEdge.java
168
Node newNode = (Node)prototype.clone();
graph.add(newNode, mousePoint);
}
...
repaint();
}
169
Add New Edge
170
Enhancing the Framework
How to implement the dialog?
Solved in chapter 7--bean properties!
CircleNode exposes color property:
Color getColor()
void setColor(Color newValue)
Property editor automatically edits color!
171
Another Framework Instance
RectangularNode
SegmentedLineEdge
GeneralPathEdge uses general path for containment testing
ArrowHead, BentStyle enumerate arrow and line styles
MultiLineString property for class compartments
ClassNode, ClassRelationshipEdge, ClassDiagramGraph
No change to basic framework!
Edge Properties
172
Multiline String Property Editor
173
Can add 3 simple graph editor classes to that framework
App tracks framework evolution at no cost to app programmer
174
Object-Oriented Design & Patterns
Cay S. Horstmann
Chapter 9
Multithreading
Chapter Topics
Thread Basics
Thread Synchronization
Animation
Threads
Thread: program unit that is executed independently
Multiple threads run simultaneously
Virtual machine executes each thread for short time slice
Thread scheduler activates, deactivates threads
Illusion of threads running in parallel
Multiprocessor computers: threads actually run in parallel
175
Running Threads
Define class that implements Runnable
Runnable has one method
void run()
Place thread action into run method
Construct object of runnable class
Construct thread from that object
Start thread
Running Threads
public class MyRunnable implements Runnable
{
public void run()
{
thread action
}
}
...
Runnable r = new MyRunnable();
Thread t = new Thread(t);
t.start();
Thread Example
Run two threads in parallel
Each thread prints 10 greetings
Thread Example
Ch9/greeting/GreetingProducer.java
Ch9/greeting/ThreadTest.java
176
Thread Example
Note: output not exactly interleaved
1: Hello, World!
1: Goodbye, World!
2: Hello, World!
2: Goodbye, World!
3: Hello, World!
3: Goodbye, World!
4: Hello, World!
4: Goodbye, World!
5: Hello, World!
5: Goodbye, World!
6: Hello, World!
6: Goodbye, World!
7: Hello, World!
7: Goodbye, World!
8: Goodbye, World!
8: Hello, World!
9: Goodbye, World!
9: Hello, World!
10: Goodbye, World!
10: Hello, World!
177
Thread States
Each thread has
o thread state
o priority
Thread states:
o new (before start called)
o runnable
o blocked
o dead (after run method exits)
Thread States
178
Blocked Thread State
Reasons for blocked state:
o Sleeping
o Waiting for I/O
o Waiting to acquire lock (later)
o Waiting for notification (later)
Unblocks only if reason for block goes away
Scheduling Threads
Scheduler activates new thread if
o a thread has completed its time slice
o a thread has blocked itself
o a thread with higher priority has become runnable
Scheduler determines new thread to run
o looks only at runnable threads
o picks one with max priority
Terminating Threads
Thread terminates when run exits
Sometimes necessary to terminate running thread
Don't use deprecated stop method
Interrupt thread by calling interrupt
Thread must cooperate and exit its run
Thread has chance to clean up
179
Sensing Interruptions
Thread could occasionally call
Thread.currentThread().isInterrupted()
sleep, wait throw InterruptedException when thread interrupted
. . . and then the interruption status is cleared!
More robust: Catch exception and react to interruption
Recommendation: Terminate run when sensing interruption
Sensing Interruptions
public class MyRunnable implements Runnable
{
public void run()
{
try
{
while (...)
{
do work
Thread.sleep(...);
}
}
catch (InterruptedException e) {}
clean up
}
}
Thread Synchronization
Use bounded queue from chapter 3
Each producer thread inserts greetings
Each consumer thread removes greetings
Two producers, one consumer
Producer Thread
int i = 1;
while (i <= repetitions)
{
if (!queue.isFull())
{
queue.add(i + ": " + greeting); i++;
}
Thread.sleep((int)(Math.random() * DELAY));
}
Consumer Thread
180
int i = 1;
while (i <= repetitions)
{
if (!queue.isEmpty())
{
Object greeting = queue.removeFirst();
System.out.println(greeting);
i++;
}
Thread.sleep((int)(Math.random() * DELAY));
}
Ch9/queue1/ThreadTest.java
Ch9/queue1/Producer.java
Ch9/queue1/Consumer.java
Ch9/queue1/Queue.java
181
Object Locks
Each object has a lock
Thread can lock, unlock object
No other thread can lock object until unlocked
Use synchronized method
Calling synchronized method locks implicit parameter
No other thread can call another synchronized method on same object
Place thread-sensitive code inside synchronized methods
public synchronized void add(Object anObject) { ... }
182
Scenario with Synchronized Methods
First thread calls add and executes
elements[tail] = anObject;
First thread at end of time slice
Second thread tries to call add, blocks
First thread executes
tail++;
First thread completes add, unlocks queue
Second thread unblocked
Second thread calls add
Visualizing Locks
Object = phone booth
Thread = person
Locked object = closed booth
Blocked thread = person waiting for booth to open
Visualizing Locks
183
Deadlocks
Not enough to synchronize add,removeFirst
if (!queue.isFull()) queue.add(...);
can still be interrupted
Must move test inside add method
What should add do if queue is full?
Deadlocks
Consumer will remove objects
Producer needs to wait
Producer can't go to sleep inside locked object
Person sleeping in phone booth, waiting for technician?
Avoiding Deadlocks
Call wait in add method:
public synchronized void add(Object anObject)
throws InterruptedException
{
while (isFull())
wait();
}
Waiting thread is blocked
Waiting thread is added to wait set of object
Avoiding Deadlocks
To unblock waiting thread, some other thread calls notifyAll
Must be called on same object
Call when state changes
public synchronized Object removeFirst()
{
...
notifyAll();
}
All waiting threads removed from wait set, unblocked
Ch9/queue2/Queue.java
Algorithm Animation
Use thread to make progress in algorithm
Display algorithm state
184
Example: Animate Ch9/animation/MergeSorter.java
Pause inside compare method
Pass custom comparator
Comparator comp = new
Comparator()
{
public void compare(Object o1, Object o2)
{
draw current state
pause thread
return comparison result
}
};
Algorithm Animation
Algorithm Animation
Ch9/animation1/Sorter.java
Ch9/animation1/ArrayPanel.java
Ch9/animation1/AnimationTest.java
185
Gate
Works like a security gate
Sorter thread = car approaching gate
Passes through if gate open, pauses otherwise
Animation thread = security guard
Step button opens gate to let one car through
Run button deactivates gate--alway open
Gate
Animation Classes
186
187
Object-Oriented Design & Patterns
Cay S. Horstmann
Chapter 10
Chapter Topics
The ADAPTER Pattern
Actions and the COMMAND Pattern
The FACTORY METHOD Pattern
The PROXY Pattern
The SINGLETON Pattern
The VISITOR Pattern
Other Design Patterns
Adapters
Cable adapter: adapts plug to foreign wall outlet
OO Programming; Want to adapt class to foreign interface type
Example: Add CarIcon to container
Problem: Containers take components, not icons
188
Solution: Create an adapter that adapts Icon to Component
Ch10/adapter/IconAdapter.java
Ch10/adapter/IconAdapterTest.java
189
Name in Design Actual Name (Icon->Component)
Pattern
Adaptee Icon
Target JComponent
Adapter IconAdapter
Client The class that wants to add icons into a container
targetMethod() paintComponent(), getPreferredSize()
adapteeMethod() paintIcon(), getIconWidth(),
getIconHeight()
190
Action has state
Action should be an object
191
Action Example
Ch10/command/CommandTest.java
Ch10/command/GreetingAction.java
192
The COMMAND Pattern
Factory Methods
Every collection can produce an iterator
Iterator iter = list.iterator()
Why not use constructors?
Iterator iter = new LinkedListIterator(list);
Drawback: not generic
Collection coll = ...;
Iterator iter = new ???(coll);
Factory method works for all collections
Iterator iter = coll.iterator();
Polymorphism!
193
1. A type (the creator) creates objects of another type (the product).
2. Subclasses of the creator type need to create different kinds of product objects.
3. Clients do not need to know the exact type of product objects.
194
Not a FACTORY METHOD
Not all "factory-like" methods are instances of this pattern
Create DateFormat instances
DateFormat formatter = DateFormat.getDateInstance();
Date now = new Date();
String formattedDate = formatter.format(now);
getDateInstance is a static method
No polymorphic creation
Proxies
Proxy: a person who is authorized to act on another person s behalf
Example: Delay instantiation of object
Expensive to load image
Not necessary to load image that user doesn't look at
Proxy defers loading until user clicks on tab
195
paintIcon loads image if not previously loaded
public void paintIcon(Component c, Graphics g, int x,
int y)
{
if (image == null) image = new ImageIcon(name);
image.paintIcon(c, g, x, y);
}
Proxies
Ch10/proxy/ImageProxy.java
Ch10/proxy/ProxyTest.java
"Every problem in computer science can be solved by an additional level of
indirection"
Another use for proxies: remote method invocation
1. A class (the real subject) provides a service that is specified by an interface type
(the subject type)
2. There is a need to modify the service in order to make it more versatile.
3. Neither the client nor the real subject should be affected by the modification.
196
The PROXY Pattern
Name in Design Pattern Actual Name (image proxy)
Subject Icon
RealSubject ImageIcon
Proxy ImageProxy
request() The methods of the Icon interface type
Client JLabel
Singletons
"Random" number generator generates predictable stream of numbers
Example: seed = (seed * 25214903917 + 11) % 248
Convenient for debugging: can reproduce number sequence
Only if all clients use the same random number generator
Singleton class = class with one instance
197
public static SingleRandom getInstance() { return
instance; }
private Random generator;
private static SingleRandom instance = new
SingleRandom();
}
Not a SINGLETON
Toolkit used for determining screen size, other window system parameters
Toolkit class returns default toolkit
Toolkit kit = Toolkit.getDefaultToolkit();
Not a singleton--can get other instances of Toolkit
Math class not example of singleton pattern
No objects of class Math are created
Inflexible Hierarchies
How can one add operations to compound hierarchies?
Example: AWT Component, Container, etc. form hierarchy
Lots of operations: getPreferredSize,repaint
Can't add new methods without modifying Component class
VISITOR pattern solves this problem
Each class must support one method
void accept(Visitor v)
Inflexible Hierarchies
198
Visitors
Visitor is an interface type
Supply a separate class for each new operation
Most basic form of accept method:
public void accept(Visitor v) { v.visit(this); }
Programmer must implement visit
Visitors
Problem: Operation may be different for different element types
Can't rely on polymorphism
Polymorphism assumes fixed set of methods, defined in superclass
Trick: Can use variable set of methods if set of classes is fixed
Supply separate visitor methods:
public interface Visitor
{
void visitElementType1(ElementType1 element);
void visitElementType2(ElementType2 element);
...
void visitElementTypen(ElementTypen element);
}
Visitors
Example: Directory tree
Two kinds of elements: DirectoryNode,FileNode
Two methods in visitor interface type:
void visitDirectoryNode(DirectoryNode node)
void visitFileNode(FileNode node)
199
Double Dispatch
Each element type provides methods:
public class ElementTypei
{
public void accept(Visitor v) {
v.visitElementTypei(this); }
...
}
Completely mechanical
Example:
public class DirectoryNode
{
public void accept(Visitor v) {
v.visitDirectoryNode(this); }
...
}
Visitor Example
Standard File class denotes both files and directories
Improved design: FileNode,DirectoryNode
Common interface type: FileSystemNode
Accepts FileSystemVisitor
Visitor methods:
visitFileNode
visitDirectoryNode
Visitor Example
200
Visitor Example
Actual visitor: PrintVisitor
Prints names of files (in visitFileNode)
Lists contents of directories (in visitDirectoryNode)
Maintains indentation level
..
command
CommandTest.java
GreetingAction.java
visitor
FileNode.java
DirectoryNode.java
Visitor Example
ch10/visitor/FileSystemNode.java
ch10/visitor/FileNode.java
ch10/visitor/DirectoryNode.java
ch10/visitor/FileSystemVisitor.java
ch10/visitor/PrintVisitor.java
ch10/visitor/VisitorTest.java
201
Double Dispatch Example
DirectoryNode node = new DirectoryNode(new
File(".."));
node.accept(new PrintVisitor());
node is a DirectoryNode
Polymorphism: node.accept calls DirectoryNode.accept
That method calls v.visitDirectoryNode
v is a PrintVisitor
Polymorphism: calls PrintVisitor.visitDirectoryNode
Two polymorphic calls determine
o node type
o visitor type
1. An object structure contains element classes of multiple types, and you want to
carry out operations that depend on the object types.
2. The set of operations should be extensible over time.
3. The set of element classes is fixed.
202
1. Define a visitor interface type that has methods for visiting elements of each of
the given types.
2. Each element class defines an accept method that invokes the matching element
visitation method on the visitor parameter.
3. To implement an operation, define a class that implements the visitor interface
type and supplies the operation s action for each element type.
203
Bridge
Builder
Chain of Responsibility
Flyweight
Interpreter
Mediator
Memento
State
204