Object Oriented Design and Patterns by Cay S. Horstmann

204
1 Object-Oriented Design & Patterns Cay S. Horstmann Chapter 1 A Crash Course in Java 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

Transcript of Object Oriented Design and Patterns by Cay S. Horstmann

Page 1: Object Oriented Design and Patterns by Cay S. Horstmann

1

Object-Oriented Design & Patterns

Cay S. Horstmann

Chapter 1

A Crash Course in Java

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

Page 2: Object Oriented Design and Patterns by Cay S. Horstmann

2

"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

"Hello, World" in Java

• Construct new objects with new operator

new Greeter("World")

• Can invoke method on newly constructed object

new Greeter("World").sayHello()

• More common: store object reference in object variable

Greeter worldGreeter = new Greeter("World");

• Then invoke method on variable:

String greeting = worldGreeter.sayHello();

"Hello, World" in Java

• Construct separate class to test your class

Ch1/helloworld/GreeterTest.java

• main method is called when program starts

• main is static: it doesn't operate on any objects

• There are no objects yet when main starts

• In OO program, main constructs objects and invokes methods

Using the SDK

• Create a new directory to hold your files

• Use a text editor to prepare files (Greeter.java, GreeterTest.java)

Page 3: Object Oriented Design and Patterns by Cay S. Horstmann

3

• Open a shell window

• cd to directory that holds your files

• Compile and run

javac GreeterTest.java java GreeterTest

Note that Greeter.java is automatically compiled.

• Output is shown in shell window

Using the SDK

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

Page 4: Object Oriented Design and Patterns by Cay S. Horstmann

4

Documentation Comments

• Delimited by /** ... */

• First sentence = summary

• @param parameter explanation

• @return explanation

• Javadoc utility extracts HTML file

Documentation Comments - Summary

Page 5: Object Oriented Design and Patterns by Cay S. Horstmann

5

Documentation Comments - Detail

Page 6: Object Oriented Design and Patterns by Cay S. Horstmann

6

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!

Documentation Comments - API Docs

Page 7: Object Oriented Design and Patterns by Cay S. Horstmann

7

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:

for (int i = 1; i <= n; i++) { . . . } // i no longer defined here

Page 8: Object Oriented Design and Patterns by Cay S. Horstmann

8

Object References

• Object variable holds a reference • Greeter worldGreeter = new Greeter("World");

• Can have multiple references to the same object

Greeter anotherGreeter = worldGreeter;

• After applying mutator method, all references access modified object

anotherGreeter.setName("Dave"); // now worldGreeter.sayHello() returns "Hello, Dave!"

The null Reference

• null refers to no object

• Can assign null to object variable:

worldGreeter = null;

• Can test whether reference is null

if (worldGreeter == null) . . .

• Dereferencing null causes NullPointerException

The this Reference

Page 9: Object Oriented Design and Patterns by Cay S. Horstmann

9

• Refers to implicit parameter of method call

• Example: Equality testing

public boolean equals(Greeter other) { if (this == other) return true; return name.equals(other.name); }

• Example: Constructor

public Greeter(String name) { this.name = name; }

Parameter Passing

• Java uses "call by value":

Method receives copy of parameter value

• Copy of object reference lets method modify object

public void copyNameTo(Greeter other) { other.name = this.name; }

• Greeter worldGreeter = new Greeter("World"); Greeter daveGreeter = new Greeter("Dave"); worldGreeter.copyNameTo(daveGreeter);

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); }

Page 10: Object Oriented Design and Patterns by Cay S. Horstmann

10

• 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

• Unique package names: start with reverse domain name

Packages

• Add package statement to top of file

package edu.sjsu.cs.cs151.alice; public class Greeter { . . . }

• Class without package name is in "default package"

• Full name of class = package name + class name

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

• Can import all classes from a package

import java.util.*;

Importing Packages

• Cannot import from multiple packages

Page 11: Object Oriented Design and Patterns by Cay S. Horstmann

11

import java.*.*; // NO

• If a class occurs in two imported packages, import is no help.

import java.util.*; import java.sql.*; . . . java.util.Date d; // Date also occurs in java.sql

• Never need to import java.lang.

Packages and Directories

• Package name must match subdirectory name.

edu.sjsu.cs.sjsu.cs151.alice.Greeter

must be in subdirectory

basedirectory/edu/sjsu/cs/sjsu/cs151/alice

• Always compile from the base directory

javac edu/sjsu/cs/sjsu/cs151/alice/Greeter.java

or

javac edu\sjsu\cs\sjsu\cs151\alice\Greeter.java

• Always run from the base directory

java edu.sjsu.cs.cs151.alice.GreeterTest

Exception Handling

• Example: NullPointerException

Page 12: Object Oriented Design and Patterns by Cay S. Horstmann

12

String name = null; int n = name.length(); // ERROR

• Cannot apply a method to null

• Virtual machine throws exception

• Unless there is a handler, program exits with stack trace

Exception in thread "main" java.lang.NullPointerException at Greeter.sayHello(Greeter.java:25) at GreeterTest.main(GreeterTest.java:6)

Checked and Unchecked Exceptions

• Compiler tracks only checked exceptions

• NullPointerException is not checked

• IOException is checked

• Generally, checked exceptions are thrown for reasons beyond the programmer's

control

• Two approaches for dealing with checked exceptions

o Declare the exception in the method header (preferred)

o Catch the exception

Declaring Checked Exceptions

• Example: Opening a file may throw FileNotFoundException:

public void read(String filename) throws FileNotFoundException { FileReader reader = new FileReader(filename); . . . }

• Can declare multiple exceptions

public void read(String filename) throws IOException, ClassNotFoundException

public static void main(String[] args) throws IOException, ClassNotFoundException

Catching Exceptions

• try { code that might throw an IOException } catch (IOException exception) {

Page 13: Object Oriented Design and Patterns by Cay S. Horstmann

13

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);

The finally Clause

• Cleanup needs to occur during normal and exceptional processing

• Example: Close a file • FileReader reader = null;

try { reader = new FileReader(name); ... } finally { if (reader != null) reader.close(); }

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"

• Use equals to compare strings

if (greeting.equals("Hello"))

• == only tests whether the object references are identical: if ("Hello".substring(1, 3) == "el") ... // NO!

StringTokenizer

Page 14: Object Oriented Design and Patterns by Cay S. Horstmann

14

• Use StringTokenizer to break string into substrings

String countries = "Germany,France,Italy"; StringTokenizer tokenizer = new StringTokenizer(countries, ","); while (tokenizer.hasMoreTokens()) { String country = tokenizer.nextToken(); ... }

String concatenation

• + operator concatenates strings:

"Hello, " + name

• If one argument of + is a string, the other is converted into a string:

int n = 7; String greeting = "Hello, " + n; // yields "Hello, 7"

• toString method is applied to objects

Date now = new Date(); String greeting = "Hello, " + now; // concatenates now.toString() // yields "Hello, Wed Jan 17 16:57:18 PST 2001"

Converting Strings to Numbers

• Use static methods Integer.parseInt Double.parseDouble

• Example:

String input = "7"; int n = Integer.parseInt(input); // yields integer 7

• If string doesn't contain a number, throws a

NumberFormatException(unchecked)

Reading Input

• Use input dialog:

String input = JOptionPane.showInputDialog("How old are you?");

Page 15: Object Oriented Design and Patterns by Cay S. Horstmann

15

• If user cancels, result is null:

if (input != null) age = Integer.parseInt(input);

Reading Input

• Must call System.exit(0)

• Ch1/input1/InputTest.java

• Also have message dialog

JOptionPane.showMessageDialog(null, "Hello, World");

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:

BufferedReader console = new BufferedReader( new InputStreamReader(System.in)); System.out.println("How old are you?"); String input = console.readLine(); int age = Integer.parseInt(input);

• Ch1/input2/InputTest.java

The ArrayList class

Page 16: Object Oriented Design and Patterns by Cay S. Horstmann

16

• Collects objects of any class type

• add appends to the end

ArrayList countries = new ArrayList(); countries.add("Belgium"); countries.add("Italy"); countries.add("Thailand");

• size method yields number of elements for (int i = 0; i < countries.size(); i++) . . .

• get gets an element; must cast to correct type: String country = (String)countries.get(i);

• set sets an element countries.set(1, "France");

The ArrayList class

• Insert and remove elements in the middle countries.add(1, "Germany"); countries.remove(0);

• Not efficient--use linked lists if needed frequently

Linked Lists

• Efficient insertion and removal

• add appends to the end

Page 17: Object Oriented Design and Patterns by Cay S. Horstmann

17

LinkedList countries = new LinkedList(); countries.add("Belgium"); countries.add("Italy"); countries.add("Thailand");

• Use iterators to edit in the middle

List Iterators

• Iterator points between list elements

• next retrieves element and advances iterator ListIterator iterator = countries.listIterator(); while (iterator.hasNext()) { String country = (String) iterator.next(); . . . }

• add adds element before iterator position

• remove removes element returned by last call to next

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];

Page 18: Object Oriented Design and Patterns by Cay S. Horstmann

18

• Array variable is a reference

Arrays

• length member yields number of elements

for (int i = 0; i < numbers.length; i++)

• Can have array of length 0; not the same as null:

numbers = new int[0];

• Array access with [] operator: int n = numbers[i];

• Multidimensional array

int[][] table = new int[10][20]; int t = table[i][j];

Command-Line Arguments

• void main(String[] args)

• args parameter of main is initialized with command-line arguments

• Example: java GreeterTest Mars

Page 19: Object Oriented Design and Patterns by Cay S. Horstmann

19

• args.length is 1

args[0] is "Mars"

Static Fields

• Shared among all instances of a class

• Example: shared random number generator

public class Greeter { . . . private static Random generator; }

• Example: shared constants

public class Math { . . . public static final double PI = 3.14159265358979323846; }

Static Methods

• Don't operate on objects

• Example: Math.sqrt

• Example: factory method

public static Greeter getRandomInstance() { if (generator.nextBoolean()) // note: generator is static field return new Greeter("Mars"); else return new Greeter("Venus"); }

• Invoke through class:

Greeter g = Greeter.getRandomInstance();

• Static fields and methods should be rare in OO programs

Programming Style: Case Convention

• variables, fields and methods:

start with lowercase, use caps for new words:

Page 20: Object Oriented Design and Patterns by Cay S. Horstmann

20

name sayHello

• Classes:

start with uppercase, use caps for new words:

Greeter ArrayList

• Constants:

use all caps, underscores to separate words

PI MAX_VALUE

Programming Style: Property Access

• Common to use get/set prefixes:

String getName() void setName(String newValue)

• Boolean property has is/set prefixes:

public boolean isPolite() public void setPolite(boolean newValue)

Programming Style: Braces

• "Allman" brace style: braces line up

public String sayHello() { return "Hello, " + name + "!"; }

• "Kernighan and Ritchie" brace style: saves a line

public String sayHello() { return "Hello, " + name + "!"; }

Programming Style: Fields

• Some programmers put fields before methods:

public class Greeter {

Page 21: Object Oriented Design and Patterns by Cay S. Horstmann

21

private String name; public Greeter(String aName) { . . . } . . . }

• From OO perspective, it is better to list the public interface first

• All fields should be private

• Don't use default (package) visibility

Programming Style: Miscellaneous

• Spaces around operators, after keywords, but not after method names

Good: if (x > Math.sqrt(y)) Bad: if(x>Math.sqrt (y))

• Don't use C-style arrays:

Good: int[] numbers Bad: int numbers[]

• No magic numbers

Good: h = HASH_MULTIPLIER * h + val[off]; Bad: h = 31 * h + val[off];

Page 22: Object Oriented Design and Patterns by Cay S. Horstmann

22

Object-Oriented Design & Patterns

Cay S. Horstmann

Chapter 2

The Object-Oriented Design Process

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

From Problem to Code

Page 23: Object Oriented Design and Patterns by Cay S. Horstmann

23

Three Phases:

• Analysis

• Design

• Implementation

Case Study: Voice Mail System

Analysis Phase

Functional Specification

• Completely defines tasks to be solved

• Free from internal contradictions

• Readable both by domain experts and software developers

• Reviewable by diverse interested parties

• Testable against reality

Design Phase

Goals

• Identify classes

• Identify behavior of classes

• Identify relationships among classes

Artifacts

• Textual description of classes and key methods

• Diagrams of class relationships

• Diagrams of important usage scenarios

• State diagrams for objects with rich state

Implementation Phase

• Implement and test classes

• Combine classes into program

• Avoid "big bang" integration

• Prototypes can be very useful

Object and Class Concepts

• Object: Three characteristic concepts

o State

Page 24: Object Oriented Design and Patterns by Cay S. Horstmann

24

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

• MessageQueue stores messages

• Don't worry yet how the queue is implemented

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:

• Add message to tail

• Remove message from head

• Test whether queue is empty

Responsibilities

Page 25: Object Oriented Design and Patterns by Cay S. Horstmann

25

• 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

void print() // prints to System.out

with

String getText() // can print anywhere

• Removes dependence on System, PrintStream

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:

public class Mailbox { . . . private Greeting myGreeting; }

Page 26: Object Oriented Design and Patterns by Cay S. Horstmann

26

• 1 : n relationship:

public class MessageQueue { . . . private ArrayList elements; }

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

Sample Use Case

Leave a Message

1. Caller dials main number of voice mail system

2. System speaks prompt

Enter mailbox number followed by #

3. User types extension number

4. System speaks

You have reached mailbox xxxx. Please leave a message now

5. Caller speaks message

6. Caller hangs up

Page 27: Object Oriented Design and Patterns by Cay S. Horstmann

27

7. System places message in mailbox

Sample Use Case -- Variations

Variation #1

1.1. In step 3, user enters invalid extension number

1.2. Voice mail system speaks You have typed an invalid mailbox number.

1.3. Continue with step 2.

Variation #2

2.1. After step 4, caller hangs up instead of speaking message

2.3. Voice mail system discards empty message

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

Page 28: Object Oriented Design and Patterns by Cay S. Horstmann

28

• 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

Page 29: Object Oriented Design and Patterns by Cay S. Horstmann

29

• Rectangle with class name

• Optional compartments

o Attributes

o Methods

• Include only key attributes and methods

Class Diagrams

Class Relationships

Multiplicities

Page 30: Object Oriented Design and Patterns by Cay S. Horstmann

30

• 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

Page 31: Object Oriented Design and Patterns by Cay S. Horstmann

31

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

Page 32: Object Oriented Design and Patterns by Cay S. Horstmann

32

Object Construction

State Diagram

• Use for classes whose objects have interesting states

Page 33: Object Oriented Design and Patterns by Cay S. Horstmann

33

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) { }

• Don't compile file, just run Javadoc

• Makes a good starting point for code later

Case Study: Voice Mail System

• Use text for voice, phone keys, hangup

• 1 2 ... 0 # on a single line means key

• H on a single line means "hang up"

• All other inputs mean voice

• In GUI program, will use buttons for keys (see ch. 4)

Use Case: Reach an Extension

Page 34: Object Oriented Design and Patterns by Cay S. Horstmann

34

1. User dials main number of system

2. System speaks prompt

Enter mailbox number followed by #

3. User types extension number

4. System speaks

You have reached mailbox xxxx. Please leave a message now

Use Case: Leave a Message

1. Caller carries out Reach an Extension

2. Caller speaks message

3. Caller hangs up

4. System places message in mailbox

Use Case: Log in

1. Mailbox owner carries out Reach an Extension

2. Mailbox owner types password and # (Default password = mailbox number. To change, see Change the Passcode)

3. System plays mailbox menu:

Enter 1 to retrieve your messages. Enter 2 to change your passcode. Enter 3 to change your greeting.

Use Case: Retrieve Messages

1. Mailbox owner carries out Log in

2. Mailbox owner selects "retrieve messages" menu option

3. System plays message menu:

Press 1 to listen to the current message Press 2 to delete the current message Press 3 to save the current message Press 4 to return to the mailbox menu

4. Mailbox owner selects "listen to current message"

5. System plays current new message, or, if no more new messages, current old

message.

Note: Message is played, not removed from queue

6. System plays message menu

7. User selects "delete current message". Message is removed.

8. Continue with step 3.

Page 35: Object Oriented Design and Patterns by Cay S. Horstmann

35

Use Case: Retrieve Messages

Variation #1

1.1. Start at Step 6

1.2. User selects "save current message".

Message is removed from new queue and appended to old queue

1.3. Continue with step 3.

Use Case: Change the Greeting

1. Mailbox owner carries out Log in

2. Mailbox owner selects "change greeting" menu option

3. Mailbox owner speaks new greeting

4. Mailbox owner presses #

5. System sets new greeting

Use Case: Change the Greeting

Variation #1: Hang up before confirmation

1.1. Start at step 3.

1.2. Mailbox owner hangs up.

1.3. System keeps old greeting.

Use Case: Change the Passcode

1. Mailbox owner carries out Log in

2. Mailbox owner selects "change passcode" menu option

3. Mailbox owner dials new passcode

4. Mailbox owner presses #

5. System sets new passcode

Use Case: Change the Passcode

Variation #1: Hang up before confirmation

1.1. Start at step 3.

1.2. Mailbox owner hangs up.

1.3. System keeps old passcode.

CRC Cards for Voice Mail System

Page 36: Object Oriented Design and Patterns by Cay S. Horstmann

36

Some obvious classes

• Mailbox • Message • MailSystem

Initial CRC Cards: Mailbox

Initial CRC Cards: MessageQueue

Initial CRC Cards: MailSystem

Page 37: Object Oriented Design and Patterns by Cay S. Horstmann

37

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

Page 38: Object Oriented Design and Patterns by Cay S. Horstmann

38

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

Result of Use Case Analysis

Page 39: Object Oriented Design and Patterns by Cay S. Horstmann

39

Result of Use Case Analysis

Result of Use Case Analysis

Result of Use Case Analysis

Page 40: Object Oriented Design and Patterns by Cay S. Horstmann

40

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

Result of Use Case Analysis

Page 41: Object Oriented Design and Patterns by Cay S. Horstmann

41

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)

UML Class Diagram for Mail System

• CRC collaborators yield dependencies

• Mailbox depends on MessageQueue

• t depends on Mailbox

• Connection depends on Telephone, MailSystem, Message, Mailbox

• Telephone depends on Connection

Dependency Relationships

Page 42: Object Oriented Design and Patterns by Cay S. Horstmann

42

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

UML Class Diagram for Voice Mail System

Sequence Diagram for Use Case: Leave a message

Page 43: Object Oriented Design and Patterns by Cay S. Horstmann

43

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

Sequence Diagram for Use Case: Retrieve messages

Page 44: Object Oriented Design and Patterns by Cay S. Horstmann

44

Connection State Diagram

Java Implementation

Page 45: Object Oriented Design and Patterns by Cay S. Horstmann

45

• 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

Page 46: Object Oriented Design and Patterns by Cay S. Horstmann

46

Object-Oriented Design & Patterns

Cay S. Horstmann

Chapter 3

The Object-Oriented Design Process

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

Date Classes in Standard Library

• Many programs manipulate dates such as

"Saturday, February 3, 2001"

• Date class:

Date now = new Date(); // constructs current date/time

Page 47: Object Oriented Design and Patterns by Cay S. Horstmann

47

System.out.println(now.toString()); // prints date such as // Sat Feb 03 16:34:10 PST 2001

• Date class encapsulates point in time

Methods of the Date class

boolean after(Date other)

Tests if this date is after the specified date

boolean before(Date other)

Tests if this date is before the specified date

int compareTo(Date other)

Tells which date came before the other

long getTime() Returns milliseconds since the epoch

(1970-01-01 00:00:00 GMT)

void setTime(long n) Sets the date to the given number of milliseconds since

the epoch

Methods of the Date class

• Deprecated methods omitted

• Date class methods supply total ordering on Date objects

• Convert to scalar time measure

• Note that before/after not strictly necessary

(Presumably introduced for convenience)

Points in Time

The GregorianCalendar Class

• The Date class doesn't measure months, weekdays, etc.

• That's the job of a calendar

• A calendar assigns a name to a point in time

Page 48: Object Oriented Design and Patterns by Cay S. Horstmann

48

• Many calendars in use:

o Gregorian

o Contemporary: Hebrew, Arabic, Chinese

o Historical: French Revolutionary, Mayan

Date Handling in the Java Library

Designing a Day Class

• Custom class, for teaching/learning purpose

• Use the standard library classes, not this class, in your own programs

• Day encapsulates a day in a fixed location

• No time, no time zone

• Use Gregorian calendar

Designing a Day Class

• Answer questions such as

o How many days are there between now and the end of the year?

o What day is 100 days from now?

Designing a Day Class

Page 49: Object Oriented Design and Patterns by Cay S. Horstmann

49

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:

Day later = today.addDays(999);

• Mathematical relationship:

d.addDays(n).daysFrom(d) == n d1.addDays(d2.daysFrom(d1)) == d2

• Clearer when written with "overloaded operators":

(d + n) - d == n d1 + (d2 - d1) == d2

• Constructor Date(int year, int month, int date)

• getYear, getMonth, getDate acccesors

Implementing a Day Class

• Straightforward implementation:

private int year private int month private int date

• addDays/daysBetween tedious to implement

o April, June, September, November have 30 days

Page 50: Object Oriented Design and Patterns by Cay S. Horstmann

50

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

Implementing a Day Class

• Ch3/code/day1/Day.java

• Ch3/code/day1/DayTest.java

• Note private helper methods

• Computations are inefficient: a day at a time

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?

The Importance of Encapsulation

• Even a simple class can benefit from different implementations

• Users are unaware of implementation

• Public instance variables would have blocked improvement

o Can't just use text editor to replace all

d.year

with

d.getYear()

o How about

Page 51: Object Oriented Design and Patterns by Cay S. Horstmann

51

d.year++? o d = new Day(d.getDay(), d.getMonth(), d.getYear() + 1)

o Ugh--that gets really inefficient in Julian representation

• Don't use public fields, even for "simple" classes

Accessors and Mutators

• Mutator: Changes object state

• Accessor: Reads object state without changing it

• Day class has no mutators!

• Class without mutators is immutable

• String is immutable

• Date and GregorianCalendar are mutable

Don't Supply a Mutator for every Accessor

• Day has getYear, getMonth, getDate accessors

• Day does not have setYear, setMonth,setDate mutators

• These mutators would not work well

o Example:

Day deadline = new Day(2001, 1, 31); deadline.setMonth(2); // ERROR deadline.setDate(28);

o Maybe we should call setDate first?

Day deadline = new Day(2001, 2, 28); deadline.setDate(31); // ERROR deadline.setMonth(3);

• GregorianCalendar implements confusing rollover.

o Silently gets the wrong result instead of error.

• Immutability is useful

Sharing Mutable References

• References to immutable objects can be freely shared

• Don't share mutable references

• Example

class Employee { . . . public String getName() { return name; } public double getSalary() { return salary; } public Date getHireDate() { return hireDate; }

Page 52: Object Oriented Design and Patterns by Cay S. Horstmann

52

private String name; private double salary; private Date hireDate; }

Sharing Mutable References

• Pitfall:

Employee harry = . . .; Date d = harry.getHireDate(); d.setTime(t); // changes Harry's state!!!

• Remedy: Use clone

public Date getHireDate() { return (Date)hireDate.clone(); }

Sharing Mutable References

Final Instance Fields

• Good idea to mark immutable instance fields as final private final int day;

• final object reference can still refer to mutating object private final ArrayList elements;

• elements can't refer to another array list

• The contents of the array list can change

Separating Accessors and Mutators

Page 53: Object Oriented Design and Patterns by Cay S. Horstmann

53

• 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();

• Yields current token and advances iteration

• What if I want to read the current token again?

Separating Accessors and Mutators

• Better interface:

String getToken(); void nextToken();

• Even more convenient:

String getToken(); String nextToken(); // returns current

• Refine rule of thumb:

Mutators can return a convenience value, provided there is also an accessor to get

the same value

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)

mutates a but not b

Side Effects

• Date formatting (basic):

Page 54: Object Oriented Design and Patterns by Cay S. Horstmann

54

SimpleDateFormat formatter = . . .; String dateString = "January 11, 2012"; Date d = formatter.parse(dateString);

• Advanced:

FieldPosition position = . . .; Date d = formatter.parse(dateString, position);

• Side effect: updates position

• Design could be better: add position to formatter state

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");

• Your classes may need to run in an environment without System.out

• Rule of thumb: Minimize side effects

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

Page 55: Object Oriented Design and Patterns by Cay S. Horstmann

55

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:

public class Mailbox { public addMessage(Message aMessage) { ... } public Message getCurrentMessage() { ... } public Message removeCurrentMessage() { ... } public void processCommand(String command) { ... } ... }

Completeness

• Support operations that are well-defined on abstraction

• Potentially bad example: Date

Date start = new Date(); // do some work Date end = new Date();

• How many milliseconds have elapsed?

• No such operation in Date class

• Does it fall outside the responsibility?

• After all, we have before, after, getTime

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.

Page 56: Object Oriented Design and Patterns by Cay S. Horstmann

56

• 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

LinkedList countries = new LinkedList(); countries.add("A"); countries.add("B"); countries.add("C");

• Iterate through list:

ListIterator iterator = countries.listIterator(); while (iterator.hasNext()) System.out.println(iterator.next());

Clarity

• Iterator between elements

• Like blinking caret in word processor

• add adds to the left of iterator (like word processor):

• Add X before B:

ListIterator iterator = countries.listIterator(); // |ABC iterator.next(); // A|BC iterator.add("France"); // AX|BC

• To remove first two elements, you can't just "backspace"

• remove does not remove element to the left of iterator

• From API documentation:

Removes from the list the last element that was returned by next or previous. This

call can only be made once per call to next or previous. It can be made only if add

has not been called after the last call to next or previous.

• Huh?

Consistency

• Related features of a class should have matching

o names

o parameters

o return values

o behavior

Page 57: Object Oriented Design and Patterns by Cay S. Horstmann

57

• Bad example:

new GregorianCalendar(year, month - 1, day)

• Why is month 0-based?

Consistency

• Bad example: String class

s.equals(t) / s.equalsIgnoreCase(t)

• But

boolean regionMatches(int toffset, String other, int ooffset, int len) boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)

• Why not regionMatchesIgnoreCase?

• Very common problem in student code

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

Page 58: Object Oriented Design and Patterns by Cay S. Horstmann

58

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); }

• What happens if precondition not fulfilled? • IndexOutOfBoundsException

• Other implementation may have different behavior

Circular Array Implementation

• Efficient implementation of bounded queue

• Avoids inefficient shifting of elements

• Circular: head, tail indexes wrap around

• Ch3/queue/MessageQueue.java

Inefficient Shifting of Elements

A Circular Array

Page 59: Object Oriented Design and Patterns by Cay S. Horstmann

59

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;

• Throws AssertionError if condition false and checking enabled

Assertions

Page 60: Object Oriented Design and Patterns by Cay S. Horstmann

60

public Message removeFirst() { assert count > 0 : "violated precondition size() > 0"; Message r = elements[head]; . . . }

• During testing, run with

java -enableassertions MyProg

Exceptions in the Contract

/** . . . @throws IllegalArgumentException if queue is empty */ public Message removeFirst() { if (count == 0) throw new IllegalArgumentException(); Message r = elements[head]; . . . }

• Exception throw part of the contract

• Caller can rely on behavior

• Exception throw not result of precondition violation

• This method has no precondition

Postconditions

• Conditions that the service provider guarantees

• Every method promises description, @return

• Sometimes, can assert additional useful condition

• Example: add method

@postcondition size() > 0

• Postcondition of one call can imply precondition of another:

q.add(m1); m2 = q.remove();

Class Invariants

• Condition that is

o true after every constructor

Page 61: Object Oriented Design and Patterns by Cay S. Horstmann

61

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

0 <= head && head < elements.length

• First check it's true for constructor

o Sets head = 0

o Need precondition size > 0!

• Check mutators. Start with add

o Sets headnew = (headold + 1) % elements.length

o We know headold > 0 (Why?)

o % operator property:

0 <= headnew && headnew < elements.length

• What's the use? Array accesses are correct!

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

Page 62: Object Oriented Design and Patterns by Cay S. Horstmann

62

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

public void testAdd() { Day d1 = new Day(1970, 1, 1); int n = 1000; Day d2 = d1.addDays(n); assert d2.daysFrom(d1) == n; }

Page 63: Object Oriented Design and Patterns by Cay S. Horstmann

63

Object-Oriented Design & Patterns

Cay S. Horstmann

Chapter 4

Interfaces and Polymorphism

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:

Page 64: Object Oriented Design and Patterns by Cay S. Horstmann

64

JOptionPane.showMessageDialog(null, "Hello, World!");

• Note icon to the left

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

Page 65: Object Oriented Design and Patterns by Cay S. Horstmann

65

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

The Icon Interface Type and Implementing Classes

Polymorphism

• public static void showMessageDialog(...Icon anIcon)

Page 66: Object Oriented Design and Patterns by Cay S. Horstmann

66

• 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?

int width = anIcon.getIconWidth();

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

A Variable of Interface Type

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.

showMessageDialog(..., new MarsIcon(50))

• Polymorphism: Select different methods according to actual object type

Page 67: Object Oriented Design and Patterns by Cay S. Horstmann

67

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

public void paintIcon(Component c, Graphics g, int x, int y) { Graphics2D g2 = (Graphics2D)g; . . . }

• Can draw any object that implements Shape interface

Shape s = . . .; g2.draw(s);

Drawing Rectangles and Ellipses

• Rectangle2D.Double constructed with

o top left corner

o width

o height • g2.draw(new Rectangle2D.Double(x, y, width, height));

• For Ellipse2D.Double, specify bounding box

Drawing Ellipses

Page 68: Object Oriented Design and Patterns by Cay S. Horstmann

68

Drawing Line Segments

• Point2D.Double is a point in the plane

• Line2D.Double joins to points

Point2D.Double start = new Point2D.Double(x1, y1); Point2D.Double end = new Point2D.Double(x2, y2); Shape segment = new Line2D.Double(start, end); g2.draw(segment);

Relationship Between Shape Classes

Drawing Text

Page 69: Object Oriented Design and Patterns by Cay S. Horstmann

69

• g2.drawString(text, x, y);

• x, y are base point coordinates

Filling Shapes

• Fill interior of shape

g2.fill(shape);

• Set color for fills or strokes: g2.setColor(Color.red);

• Program that draws car

Ch4/icon3/CarIcon.java

The Comparable Interface Type

• Collections has static sort method:

ArrayList a = . . . Collections.sort(a);

• Objects in list must implement the Comparable interface type

public interface Comparable { int compareTo(Object other); }

• object1.compareTo(object2) returns

o Negative number if object1 less than object2

o 0 if objects identical

Page 70: Object Oriented Design and Patterns by Cay S. Horstmann

70

o Positive number if object1 greater than object2

The Comparable Interface Type

• sort method compares and rearranges elements if (object1.compareTo(object2) > 0) . . .

• String class implements Comparable interface type: lexicographic (dictionary)

order

• Country class: compare countries by area

Ch4/sort1/Country.java

Ch4/sort1/CountrySortTest.java

The Comparator interface type

• How can we sort countries by name?

• Can't implement Comparable twice!

• Comparator interface type gives added flexibility

public interface Comparator { int compare(Object object1, Object object2); }

• Pass comparator object to sort:

Collections.sort(list, comp);

The Comparator interface type

• Ch4/sort2/CountryComparatorByName.java

Ch4/sort2/ComparatorTest.java

• Comparator object is a function object

• This particular comparator object has no state

• State can be useful, e.g. flag to sort in ascending or descending order

Anonymous Classes

• No need to name objects that are used only once

Collections.sort(countries, new CountryComparatorByName());

• No need to name classes that are used only once

Comparator comp = new Comparator()

Page 71: Object Oriented Design and Patterns by Cay S. Horstmann

71

{ 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

Page 72: Object Oriented Design and Patterns by Cay S. Horstmann

72

JButton helloButton = new JButton("Say Hello");

• Set content pane layout

Container contentPane = frame.getContentPane(); container.setLayout(new FlowLayout());

• Add components to content pane

contentPane.add(helloButton);

• Ch4/frame/FrameTest.java

User Interface Actions

• Previous program's buttons don't have any effect

• Add listener object(s) to button

• Belong to class implementing ActionListener interface type

public interface ActionListener { int actionPerformed(ActionEvent event); }

• Listeners are notified when button is clicked

User Interface Actions

• Add action code into actionPerformed method

• Gloss over routine code

helloButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { textField.setText("Hello, World"); } });

• When button is clicked, text field is set

Accessing Variables from Enclosing Scope

Page 73: Object Oriented Design and Patterns by Cay S. Horstmann

73

• 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 = ...;

User Interface Actions

• Constructor attaches listener:

helloButton.addActionListener(listener);

• Button remembers all listeners

• When button clicked, button notifies listeners

listener.actionPerformed(event);

• Listener sets text of text field

textField.setText("Hello, World!");

• Ch4/action1/ActionTest.java

Constructing Related Actions

• Write helper method that constructs objects

• Pass variable information as parameters

• Declare parameters final

public static ActionListener createGreetingButtonListener( final String message) { return new ActionListener() { public void actionPerformed(ActionEvent event) { textField.setText(message); } }; }

Timers

• Supply delay, action listener ActionListener listener = ...; final int DELAY = 1000; // 1000 millisec = 1 sec

Page 74: Object Oriented Design and Patterns by Cay S. Horstmann

74

Timer t = new Timer(DELAY, listener); t.start();

• Action listener called when delay elapsed

• Ch4/timer/TimerTest.java

Defining a New Interface Type

• Use timer to move car shapes

• Draw car with CarShape

• Two responsibilities:

o Draw shape

o Move shape

• Define new interface type MoveableShape

CRC Card for the MoveableShape Interface Type

Defining a New Interface Type

• Name the methods to conform to standard library

Page 75: Object Oriented Design and Patterns by Cay S. Horstmann

75

• 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; } . . . }

Implementing the Animation

• Label contains icon that draws shape

• Timer action moves shape, calls repaint on label

• Label needs Icon, we have MoveableShape

• Supply ShapeIcon adapter class

• ShapeIcon.paintIcon calls MoveableShape.draw

Implementing the Animation

• Ch4/animation/MoveableShape.java

• Ch4/animation/ShapeIcon.java

• Ch4/animation/AnimationTest.java

• Ch4/animation/CarShape.java

Implementing the Animation

Page 76: Object Oriented Design and Patterns by Cay S. Horstmann

76

Page 77: Object Oriented Design and Patterns by Cay S. Horstmann

77

Object-Oriented Design & Patterns

Cay S. Horstmann

Chapter 5

Patterns and GUI Programming

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()) {

Page 78: Object Oriented Design and Patterns by Cay S. Horstmann

78

Object current = iterator.next(); . . . }

• Why iterators?

Classical List Data Structure

• Traverse links directly

Link currentLink = list.head; while (currentLink != null) { Object current = currentLink.data; currentLink = currentLink.next; }

• Exposes implementation

• Error-prone

High-Level View of Data Structures

• Queue

• Array with random access

• List

???

List with Cursor

Page 79: Object Oriented Design and Patterns by Cay S. Horstmann

79

for (list.reset(); list.hasNext(); list.next()) { Object x = list.get(); . . . }

• Disadvantage: Only one cursor per list

• Iterator is superior concept

The Pattern Concept

• History: Architectural Patterns

• Christopher Alexander

• Each pattern has

o a short name

o a brief description of the context

o a lengthy description of the problem

o a prescription for the solution

Short Passages Pattern

Page 80: Object Oriented Design and Patterns by Cay S. Horstmann

80

Short Passages Pattern

Context

"...Long, sterile corridors set the scene for everything bad about modern architecture..."

Problem

a lengthy description of the problem, including

• 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

Short Passages Pattern

Solution

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.

Page 81: Object Oriented Design and Patterns by Cay S. Horstmann

81

Iterator Pattern

Context

1. An aggregate object contains element objects

2. Clients need access to the element objects

3. The aggregate object should not expose its internal structure

4. Multiple clients may want independent access

Iterator Pattern

Solution

1. Define an iterator that fetches one element at a time

2. Each iterator object keeps track of the position of the next element

3. If there are several aggregate/iterator variations, it is best if the aggregate and

iterator classes realize common interface types.

Iterator Pattern

Page 82: Object Oriented Design and Patterns by Cay S. Horstmann

82

Iterator Pattern

• Names in pattern are examples

• Names differ in each occurrence of pattern

Name in Design Pattern Actual Name (linked lists)

Aggregate List

ConcreteAggregate LinkedList

Iterator ListIterator

ConcreteIterator anonymous class implementing ListIterator

createIterator() listIterator()

next() next()

isDone() opposite of hasNext()

currentItem() return value of hasNext()

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

Page 83: Object Oriented Design and Patterns by Cay S. Horstmann

83

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

Page 84: Object Oriented Design and Patterns by Cay S. Horstmann

84

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

1. An object, called the subject, is source of events

2. One or more observer objects want to be notified when such an event occurs.

Solution

1. Define an observer interface type. All concrete observers implement it.

2. The subject maintains a collection of observers.

3. The subject supplies methods for attaching and detaching observers.

4. Whenever an event occurs, the subject notifies all observers.

Observer Pattern

Page 85: Object Oriented Design and Patterns by Cay S. Horstmann

85

Names in Observer Pattern

Name in Design Pattern Actual Name (Swing buttons)

Subject JButton

Observer ActionListener

ConcreteObserver the class that implements the ActionListener interface type

attach() addActionListener()

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

Page 86: Object Oriented Design and Patterns by Cay S. Horstmann

86

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

Page 87: Object Oriented Design and Patterns by Cay S. Horstmann

87

Voice Mail System GUI

• Same backend as text-based system

• Only Telephone class changes

• Buttons for keypad

• Text areas for microphone, speaker

Voice Mail System GUI

Page 88: Object Oriented Design and Patterns by Cay S. Horstmann

88

Page 89: Object Oriented Design and Patterns by Cay S. Horstmann

89

Voice Mail System GUI

• Arrange keys in panel with GridLayout:

JPanel keyPanel = new JPanel(); keyPanel.setLayout(new GridLayout(4, 3)); for (int i = 0; i < 12; i++) { JButton keyButton = new JButton(...); keyPanel.add(keyButton);

Page 90: Object Oriented Design and Patterns by Cay S. Horstmann

90

keyButton.addActionListener(...); }

Voice Mail System GUI

• Panel with BorderLayout for microphone

JPanel speakerPanel = new JPanel(); speakerPanel.setLayout(new BorderLayout()); speakerPanel.add(new JLabel("Speaker:"), BorderLayout.NORTH); speakerField = new JTextArea(10, 25); speakerPanel.add(speakerField, BorderLayout.CENTER);

Voice Mail System GUI

• Put speaker, keypads, and microphone panel into content pane

• Content pane already has BorderLayout

• Ch5/mailgui/Telephone.java

Page 91: Object Oriented Design and Patterns by Cay S. Horstmann

91

Custom Layout Manager

• Form layout

• Odd-numbered components right aligned

• Even-numbered components left aligned

• Implement LayoutManager interface type

The LayoutManager Interface Type

public interface LayoutManager { void layoutContainer(Container parent);

Page 92: Object Oriented Design and Patterns by Cay S. Horstmann

92

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

Comparator comp = new CountryComparatorByName(); Collections.sort(countries, comp);

Strategy Pattern

Context

1. A class can benefit from different variants for an algorithm

2. Clients sometimes want to replace standard algorithms with custom versions

Solution

1. Define an interface type that is an abstraction for the algorithm

2. Actual strategy classes realize this interface type.

3. Clients can supply strategy objects

4. Whenever the algorithm needs to be executed, the context class calls the

appropriate methods of the strategy object

Strategy Pattern

Page 93: Object Oriented Design and Patterns by Cay S. Horstmann

93

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

Strategy Pattern: Sorting

Name in Design Pattern Actual Name (sorting)

Context Collections

Strategy Comparator

ConcreteStrategy a class that implements Comparator

doWork() compare

Containers and Components

• Containers collect GUI components

• Sometimes, want to add a container to another container

• Container should be a component

• Composite design pattern

• Composite method typically invoke component methods

• E.g. Container.getPreferredSize invokes getPreferredSize of components

Page 94: Object Oriented Design and Patterns by Cay S. Horstmann

94

Composite Pattern

Context

1. Primitive objects can be combined to composite objects

2. Clients treat a composite object as a primitive object

Solution

1. Define an interface type that is an abstraction for the primitive objects

2. Composite object collects primitive objects

3. Composite and primitive classes implement same interface type.

4. When implementing a method from the interface type, the composite class applies

the method to its primitive objects and combines the results

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

Page 95: Object Oriented Design and Patterns by Cay S. Horstmann

95

• Approach #2: Scroll bars can surround component

JScrollPane pane = new JScrollPane(component);

• Swing uses approach #2

• JScrollPane is again a component

Scroll Bars

Decorator Pattern

Context

1. Component objects can be decorated (visually or behaviorally enhanced)

2. The decorated object can be used in the same way as the undecorated object

3. The component class does not want to take on the responsibility of the decoration

4. There may be an open-ended set of possible decorations

Decorator Pattern

Solution

1. Define an interface type that is an abstraction for the component

Page 96: Object Oriented Design and Patterns by Cay S. Horstmann

96

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

Decorator Pattern: Scroll Bars

Name in Design Pattern Actual Name (scroll bars)

Component Component

ConcreteComponent JTextArea

Decorator JScrollPane

method() a method of Component (e.g. paint)

Streams

InputStreamReader reader = new InputStreamReader(System.in); BufferedReader console = new BufferedReader(reader);

• BufferedReader takes a Reader and adds buffering

• Result is another Reader: Decorator pattern

• Many other decorators in stream library, e.g. PrintWriter

Decorator Pattern: Input Streams

Name in Design Pattern Actual Name (input streams)

Component Reader

ConcreteComponent InputStreamReader

Page 97: Object Oriented Design and Patterns by Cay S. Horstmann

97

Decorator BufferedReader

method() read

How to Recognize Patterns

• Look at the intent of the pattern

• E.g. COMPOSITE has different intent than DECORATOR

• Remember common uses (e.g. STRATEGY for layout managers)

• Not everything that is strategic is an example of STRATEGY pattern

• Use context and solution as "litmus test"

Litmus Test

• Can add border to Swing component

Border b = new EtchedBorder() component.setBorder(b);

• 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

Putting Patterns to Work

• Invoice contains line items

• Line item has description, price

Page 98: Object Oriented Design and Patterns by Cay S. Horstmann

98

• 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

Page 99: Object Oriented Design and Patterns by Cay S. Horstmann

99

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

Page 100: Object Oriented Design and Patterns by Cay S. Horstmann

100

final Invoice invoice = new Invoice(); final JTextArea textArea = new JTextArea(20, 40); ChangeListener listener = new ChangeListener() { public void stateChanged(ChangeEvent event) { textArea.setText(...); } };

Observing the Invoice

Iterating Through Invoice Items

• Invoice collect line items

• Clients need to iterate over line items

• Don't want to expose ArrayList

• May change (e.g. if storing invoices in database)

• ITERATOR pattern

Iterators

• Use standard Iterator interface type

public interface Iterator { boolean hasNext(); Object next(); void remove(); }

Page 101: Object Oriented Design and Patterns by Cay S. Horstmann

101

• 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

Page 102: Object Oriented Design and Patterns by Cay S. Horstmann

102

Formatting Invoices

Page 103: Object Oriented Design and Patterns by Cay S. Horstmann

103

Object-Oriented Design & Patterns

Cay S. Horstmann

Chapter 6

Inheritance and Abstract Classes

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

Page 104: Object Oriented Design and Patterns by Cay S. Horstmann

104

{ public Employee(String aName) { name = aName; } public void setSalary(double aSalary) { salary = aSalary; } public String getName() { return name; } public double getSalary() { return salary; } private String name; private double salary; }

• Manager is a subclass

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 private double bonus; // new field }

Modeling Specialization

Page 105: Object Oriented Design and Patterns by Cay S. Horstmann

105

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)

The Super/Sub Terminology

• Why is Manager a subclass?

• Isn't a Manager superior?

• Doesn't a Manager object have more fields?

• The set of managers is a subset of the set of employees

The Super/Sub Terminology

Page 106: Object Oriented Design and Patterns by Cay S. Horstmann

106

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

The Substitution Principle

• Formulated by Barbara Liskov

• You can use a subclass object whenever a superclass object is expected

Page 107: Object Oriented Design and Patterns by Cay S. Horstmann

107

• Example: Employee e; ... System.out.println("salary=" + e.getSalary());

• Can set e to Manager reference

• Polymorphism: Correct getSalary method is invoked

Invoking Superclass Methods

• Can't access private fields of superclass public class Manager extends Employee { public double getSalary() { return salary + bonus; // ERROR--private field } ... }

• Be careful when calling superclass method public double getSalary() { return getSalary() + bonus; // ERROR--recursive call }

Invoking Superclass Methods

• Use super keyword public double getSalary() { return super.getSalary() + bonus; }

• super is not a reference

• super turns off polymorphic call mechanism

Invoking Superclass Constructors

• Use super keyword in subclass constructor: public Manager(String aName) { super(aName); // calls superclass constructor bonus = 0; }

• Call to super must be first statement in subclass constructor

Page 108: Object Oriented Design and Patterns by Cay S. Horstmann

108

• 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:

Manager m = new Manager(); Employee e = m; e.setSalary(50000);

Postconditions, Visibility, Exceptions

• Postcondition of redefined method at least as strong

• Example: Employee.setSalary promises not to decrease salary

• Then Manager.setSalary must fulfill postcondition

• Redefined method cannot be more private.

(Common error: omit public when redefining)

• Redefined method cannot throw more checked exceptions

Graphic Programming with Inheritance

• Chapter 4: Create drawings by by implementing Icon interface type

• Now: Form subclass of JPanel

public class MyPanel extends JPanel { public void paintComponent(Graphics g) { drawing instructions go here

} ... }

• Advantage: Inherit behavior from JPanel

• Example: Can attach mouse listener to JPanel

Page 109: Object Oriented Design and Patterns by Cay S. Horstmann

109

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

public interface MouseListener { void mouseClicked(MouseEvent event); void mousePressed(MouseEvent event); void mouseReleased(MouseEvent event); void mouseEntered(MouseEvent event); void mouseExited(MouseEvent event); }

Page 110: Object Oriented Design and Patterns by Cay S. Horstmann

110

public interface MouseMotionListener { void mouseMoved(MouseEvent event); void mouseDragged(MouseEvent event); }

Mouse Adapters

• What if you just want to listen to mousePressed?

• Extend MouseAdapter

public class MouseAdapter implements MouseListener { public void mouseClicked(MouseEvent event) {} public void mousePressed(MouseEvent event) {} public void mouseReleased(MouseEvent event) {} public void mouseEntered(MouseEvent event) {} public void mouseExited(MouseEvent event) {} }

• Component constructor adds listener:

addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent event) { mouse action goes here } });

Car Mover Program

• Use the mouse to drag a car shape

• Car panel has mouse + mouse motion listeners

• mousePressed remembers point of mouse press

• mouseDragged translates car shape

• Ch6/car/CarPanel.java

• Ch6/car/CarMover.java

• Ch6/car/CarShape.java

Car Mover Program

Page 111: Object Oriented Design and Patterns by Cay S. Horstmann

111

Scene Editor

• Draws various shapes

• User can add, delete, move shapes

• User selects shape with mouse

• Selected shape is highlighted (filled in)

Scene Editor

The SceneShape Interface Type

• keep track of selection state

• draw plain or selected shape

• move shape

• hit testing: is a point (e.g. mouse position) inside?

Page 112: Object Oriented Design and Patterns by Cay S. Horstmann

112

The SceneShape Interface Type

The SceneShape Interface Type

public interface SceneShape { void setSelected(boolean b); boolean isSelected(); void draw(Graphics2D g2); void drawSelection(Graphics2D g2); void translate(double dx, double dy); boolean contains(Point2D aPoint); }

CarShape and HouseShape Classes

public class CarShape implements SceneShape { ... public void setSelected(boolean b) { selected = b; } public boolean isSelected() { return selected; } private boolean selected; } public class HouseShape implements SceneShape { ... public void setSelected(boolean b) { selected = b; } public boolean isSelected() { return selected; } private boolean selected; }

Abstract Classes

Page 113: Object Oriented Design and Patterns by Cay S. Horstmann

113

• Factor out common behavior

(setSelected, isSelected)

• Subclasses inherit common behavior

• Some methods still undefined

(draw, drawSelection, translate, contains)

public class SelectableShape implements Item { public void setSelected(boolean b) { selected = b; } public boolean isSelected() { return selected; } private boolean selected; }

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:

SelectableShape s = new SelectableShape(); // NO

Page 114: Object Oriented Design and Patterns by Cay S. Horstmann

114

• Ok to have variables of abstract class type:

SelectableShape s = new HouseShape(); // OK

Abstract Classes and Interface Types

• Abstract classes can have fields

• Interface types can only have constants (public static final)

• Abstract classes can define methods

• Interface types can only declare methods

• A class can implement any number of interface types

• In Java, a class can extend only one other class

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

Uniform Highlighting Technique

• Old approach: each shape draws its selection state

• Inconsistent

• Better approach: shift, draw, shift, draw, restore to original position

• Define in SelectableShape public void drawSelection(Graphics2D g2) { translate(1, 1); draw(g2); translate(1, 1); draw(g2); translate(-2, -2); }

Uniform Highlighting Technique

Page 115: Object Oriented Design and Patterns by Cay S. Horstmann

115

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

TEMPLATE METHOD Pattern

Context

1. An algorithm is applicable for multiple types.

2. The algorithm can be broken down into primitive operations. The primitive

operations can be different for each type

3. The order of the primitive operations doesn't depend on the type

TEMPLATE METHOD Pattern

Solution

1. Define a superclass that has a method for the algorithm and abstract methods for

the primitive operations.

Page 116: Object Oriented Design and Patterns by Cay S. Horstmann

116

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.

TEMPLATE METHOD Pattern

TEMPLATE METHOD Pattern

Name in Design Pattern Actual Name (Selectable shapes)

AbstractClass SelectableShape

ConcreteClass CarShape, HouseShape

templateMethod() drawSelection

primitiveOp1(), primitiveOp2() translate, draw

Compound Shapes

• GeneralPath: sequence of shapes

GeneralPath path = new GeneralPath(); path.append(new Rectangle(...), false); path.append(new Triangle(...), false); g2.draw(path);

• Advantage: Containment test is free path.contains(aPoint);

• Ch6/scene3/CompoundShape.java

• Ch6/scene3/HouseShape.java

Page 117: Object Oriented Design and Patterns by Cay S. Horstmann

117

Compound Shapes

Access to Superclass Features

• Why does the HouseShape constructor call add?

public HouseShape() { add(new Rectangle(...)); add(new Triangle(...)); }

• Why not just path.append(new Rectangle(...));

• HouseShape inherits path field

• HouseShape can't access path

• path is private to superclass

Page 118: Object Oriented Design and Patterns by Cay S. Horstmann

118

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

Hierarchy of Swing Components

• Base of hierarchy: Component

• Huge number of common methods:

int getWidth() int getHeight() Dimension getPreferredSize() void setBackground(Color c) . . .

• Most important subclass: Container

Hierarchy of Swing Components

Page 119: Object Oriented Design and Patterns by Cay S. Horstmann

119

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

Look and Feel

Hierarchy of Swing Components

• Base of Swing components: JComponent

• Subclass of Container

• Some Swing components are containers

• Java has no multiple inheritance

• JLabel, JPanel, ... are subclasses of JComponent

• Intermediate classes AbstractButton, JTextComponent

Hierarchy of Geometrical Shapes

• First version of Java: few shapes, integer coordinates

Point Rectangle Polygon

Page 120: Object Oriented Design and Patterns by Cay S. Horstmann

120

• Java 2: sophisticated shapes, floating-point coordinates

Point2D Rectangle2D RoundRectangle2D Line2D Ellipse2D Arc2D QuadCurve2D CubicCurve2D GeneralPath Area

• All but Point2D implement Shape interface type

Hierarchy of Geometrical Shapes

Rectangular Shapes

• Subclasses of RectangularShape:

Rectangle2D RoundRectangle2D Ellipse2D Arc2D

• RectangularShape has useful methods

getCenterX/getCenterY getMinX/getMinY getMaxX/getMaxY

Page 121: Object Oriented Design and Patterns by Cay S. Horstmann

121

getWidth/getHeight setFrameFromCenter/setFrameFromDiagonal

Float/Double Classes

• Each class has two subclasses, e.g.

Rectangle2D.Double Rectangle2D.Float

• Are also inner classes!

(Just to avoid even longer class names)

• Implementations have double/float fields

• Most methods have double parameters/return values

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) {

Page 122: Object Oriented Design and Patterns by Cay S. Horstmann

122

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:

public boolean contains(double x, double y) { double x0 = getX(); double y0 = getY(); return x >= x0 && y >= y0 && x < x0 + getWidth() && y < y0 + getHeight(); }

• No need to use inner class after construction Rectangle2D rect = new Rectangle2D.Double(5, 10, 20, 30);

Page 123: Object Oriented Design and Patterns by Cay S. Horstmann

123

TEMPLATE METHOD Pattern

Name in Design Pattern Actual Name (Rectangles)

AbstractClass Rectangle

ConcreteClass Rectangle2D.Double

templateMethod() contains

primitiveOpn() getX, getY, getWidth, getHeight

Hierarchy of Exception Classes

• Base of hierarchy: Throwable

• Two subclasses: Error, Exception

• Subclasses of Error: fatal

(out of memory, assertion failure)

• Subclasses of Exception:

o Lots of checked exceptions

(I/O, class not found)

o RuntimeException--its subclasses are unchecked

(null pointer, index out of bounds)

Hierarchy of Exception Classes

Page 124: Object Oriented Design and Patterns by Cay S. Horstmann

124

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 } . . .

• Can catch by superclass: catch (IOException exception)

catches FileNotFoundException

Defining Exception Classes

• Decide exception should be checked

• Subclass Exception or RuntimeException

• Provide two constructors

public class IllegalFormatException extends Exception { public IllegalFormatException() {} public IllegalFormatException(String reason) { super(reason); } }

• Throw exception when needed: throw new IllegalFormatException("number expected");

When Not to Use Inheritance

• From a tutorial for a C++ compiler:

public class Point { public Point(int anX, int aY) { ... } public void translate(int dx, int dy) { ... } private int x; private int y; }

Page 125: Object Oriented Design and Patterns by Cay S. Horstmann

125

public class Circle extends Point // DON'T { public Circle(Point center, int radius) { ... } public void draw(Graphics g) { ... } private int radius; }

When Not to Use Inheritance

• Huh? A circle isn't a point.

• By accident, inherited translate works for circles

• Same tutorial makes Rectangle a subclass of Point:

public class Rectangle extends Point // DON'T { public Rectangle(Point corner1, Point corner2) { ... } public void draw(Graphics g) { ... } public void translate(int dx, int dy) { ... } private Point other; }

When Not to Use Inheritance

• That's even weirder:

public void translate(double dx, double dy) { super.translate(dx, dy); other.translate(dx, dy); }

• Why did they do that?

• Wanted to avoid abstract class Shape

• Remedy: Use aggregation.

• Circle, Rectangle classes have points

When Not to Use Inheritance

• Java standard library:

public class Stack extends Vector // DON'T { Object pop() { ... } void push(Object item) { ... } ... }

• Bad idea: Inherit all Vector methods

• Can insert/remove in the middle of the stack

Page 126: Object Oriented Design and Patterns by Cay S. Horstmann

126

• Remedy: Use aggregation

public class Stack { ... private Vector elements; }

Page 127: Object Oriented Design and Patterns by Cay S. Horstmann

127

Object-Oriented Design & Patterns

Cay S. Horstmann

Chapter 7

The Java Object Model

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

Page 128: Object Oriented Design and Patterns by Cay S. Horstmann

128

• 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

Exercise: What kind of type?

• int • Rectangle • Shape • String[] • double[][]

Java Values

• value of primitive type

• reference to object of class type

• reference to array • null

• Note: Can't have value of interface type

Exercise: What kind of value?

• 13 • new Rectangle(5, 10, 20, 30); • "Hello" • new int[] { 2, 3, 5, 7, 11, 13 } • null

Subtype Relationship

S is a subtype of T if

Page 129: Object Oriented Design and Patterns by Cay S. Horstmann

129

• 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

Page 130: Object Oriented Design and Patterns by Cay S. Horstmann

130

The ArrayStoreException

• Rectangle[] is a subtype of Shape[]

• Can assign Rectangle[] value to Shape[] variable:

Rectangle[] r = new Rectangle[10]; Shape[] s = r;

• Both r and s are references to the same array

• That array holds rectangles

• The assignment s[0] = new Polygon(); compiles

• Throws an ArrayStoreException at runtime

• Each array remembers its component type

Array References

Page 131: Object Oriented Design and Patterns by Cay S. Horstmann

131

Wrapper Classes

• Primitive types aren't classes

• Use wrappers when objects are expected

• Wrapper for each type:

Integer Short Long Byte Character Float Double Boolean

• Example: ArrayList

ArrayList numbers = new ArrayList(); numbers.add(new Integer(13)); int n = ((Integer)numbers.get(0)).intValue();

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

Page 132: Object Oriented Design and Patterns by Cay S. Horstmann

132

• 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)

The Class Class

• getClass method gets class of any object

• Returns object of type Class

• Class object describes a type

Object e = new Rectangle(); Class c = e.getClass(); System.out.println(c.getName()); // prints java.awt.Rectangle

• Class.forName method yields Class object: Class c = Class.forName(java.awt.Rectangle);

• .class suffix yields Class object: Class c = Rectangle.class; // java.awt prefix not needed

• Class is a misnomer: int.class, void.class,Shape.class

An Employee Object vs. the Employee.class

Object

Page 133: Object Oriented Design and Patterns by Cay S. Horstmann

133

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

double[] a = new double[10]; Class c = a.getClass(); if (c.isArray()) System.out.println(c.getComponentType()); // prints double

• getName produces strange names for array types

[D for double[]) [[java.lang.String; for String[][]

Object: The Cosmic Superclass

Page 134: Object Oriented Design and Patterns by Cay S. Horstmann

134

• All classes extend Object

• Most useful methods: o String toString() o boolean equals(Object otherObject) o Object clone() o int hashCode()

The toString Method

• Returns a string representation of the object

• Useful for debugging

• Example: Rectangle.toString returns something like java.awt.Rectangle[x=5,y=10,width=20,height=30]

• toString used by concatenation operator • aString + anObject

means aString + anObject.toString()

• Object.toString prints class name and object address System.out.println(System.out)

yields java.io.PrintStream@d2460bf

• Implementor of PrintStream didn't override toString:

Overriding the toString Method

• Format all fields:

public class Employee { public String toString() { return getClass().getName() + "[name=" + name + ",salary=" + salary + "]"; } ... }

• Typical string:

Employee[name=Harry Hacker,salary=35000]

Overriding toString in Subclass

• Format superclass first • public class Manager extends Employee

{ public String toString()

Page 135: Object Oriented Design and Patterns by Cay S. Horstmann

135

{ return super.toString() + "[department=" + department + "]"; } ... }

• Typical string

Manager[name=Dolly Dollar,salary=100000][department=Finance]

• Note that superclass reports actual class name

The equals Method

• equals tests for equal contents

• == tests for equal location

• Used in many standard library methods

• Example: ArrayList.indexOf

/** 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; }

Overriding the equals Method

• Notion of equality depends on class

• Common definition: compare all fields

public class Employee { public boolean equals(Object otherObject)

Page 136: Object Oriented Design and Patterns by Cay S. Horstmann

136

// not complete--see below { Employee other = (Employee)otherObject; return name.equals(other.name) && salary == other.salary; } ... }

• Must cast the Object parameter to subclass

• Use == for primitive types, equals for object fields

Overriding equals in Subclass

• Call equals on superclass

public class Manager { public boolean equals(Object otherObject) { Manager other = (Manager)otherObject; return super.equals(other) && department.equals(other.department); } }

Not all equals Methods are Simple

• Two sets are equal if they have the same elements in some order

public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Set)) return false; Collection c = (Collection) o; if (c.size() != size()) return false; return containsAll(c); }

The Object.equalsMethod

• Object.equals tests for identity:

public class Object { public boolean equals(Object obj) { return this == obj; } ... }

Page 137: Object Oriented Design and Patterns by Cay S. Horstmann

137

• Override equals if you don't want to inherit that behavior

Requirements for equals Method

• reflexive: x.equals(x)

• symmetric: x.equals(y) if and only if y.equals(x)

• transitive: if x.equals(y) and y.equals(z), then x.equals(z)

• x.equals(null) must return false

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;

The Perfect equals Method

• Start with these three tests:

public boolean equals(Object otherObject) { if (this == otherObject) return true; if (otherObject == null) return false; if (getClass() != otherObject.getClass()) return false; ... }

• First test is an optimization

Hashing

• hashCode method used in HashMap, HashSet

• Computes an int from an object

• Example: hash code of String int h = 0;

Page 138: Object Oriented Design and Patterns by Cay S. Horstmann

138

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:

public class Employee { public int hashCode() { return name.hashCode() + new Double(salary).hashCode(); } ... }

Shallow and Deep Copy

• Assignment (copy = e) makes shallow copy

• Clone to make deep copy • Employee cloned = (Employee)e.clone();

Cloning

Page 139: Object Oriented Design and Patterns by Cay S. Horstmann

139

Cloning

• Object.clone makes new object and copies all fields

• Cloning is subtle

• Object.clone is protected

• Subclass must redefine clone to be public

public class Employee { public Object clone() { return super.clone(); // not complete } ... }

The Cloneable Interface

• Object.clone is nervous about cloning

• Will only clone objects that implement Cloneable interface

public interface Cloneable { }

• Interface has no methods!

• Tagging interface--used in test if x implements Cloneable

• Object.clone throws CloneNotSupportedException

• A checked exception

The clone Method

public class Employee implements Cloneable { public Object clone() { try { return super.clone(); } catch(CloneNotSupportedException e) { return null; // won't happen } } ... }

Page 140: Object Oriented Design and Patterns by Cay S. Horstmann

140

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

public class Employee implements Cloneable { public Object clone() { try { Employee cloned = (Employee)super.clone(); cloned.hireDate = (Date)hiredate.clone(); return cloned; } catch(CloneNotSupportedException e) { return null; // won't happen } } ... }

Deep Cloning

Page 141: Object Oriented Design and Patterns by Cay S. Horstmann

141

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

Employee[] staff = new Employee[2]; staff.add(new Employee(...)); staff.add(new Employee(...));

• Construct ObjectOutputStream:

ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream("staff.dat"));

Page 142: Object Oriented Design and Patterns by Cay S. Horstmann

142

• 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

How Serialization Works

• Each newly encountered object is saved

• Each object gets a serial number in the stream

• No object is saved twice

• Reference to already encountered object saved as "reference to #"

How Serialization Works

Serialing Unserializable Classes

• Some classes are not serializable

• Security? Anonymous classes? Programmer cluelessness?

• Example: Ellipse2D.Double

• How can we serialize Car?

• Suppress default serialization to avoid exception

• Mark with transient: private transient Ellipse2D frontTire;

Page 143: Object Oriented Design and Patterns by Cay S. Horstmann

143

• 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:

Field[] fields = Math.class.getDeclaredFields(); for (int i = 0; i < fields.length; i++) if (Modifier.isStatic(fields[i].getModifiers())) System.out.println(fields[i].getName());

Enumerating Constructors

• Print the names and parameter types of all Rectangle

constructors:

for (int i = 0; i < cons.length; i++) { Class[] params = cons[i].getParameterTypes(); System.out.print("Rectangle(");

Page 144: Object Oriented Design and Patterns by Cay S. Horstmann

144

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)

Getting A Single Method Descriptor

• Supply method name

• Supply array of parameter types

• Example: Get Rectangle.contains(int, int):

Method m = Rectangle.class.getDeclaredMethod( "contains", new Class[] { int.class, int.class });

• Example: Get default Rectangle constructor:

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

Page 145: Object Oriented Design and Patterns by Cay S. Horstmann

145

• 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);

• Throws exception if security manager disallows access

• Access field value:

Object value = f.get(obj); f.set(obj, value);

• Use wrappers for primitive types

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 . . .

Inspecting Array Elements

• Use static methods of Array class • Object value = Array.get(a, i);

Array.set(a, i, value);

• int n = Array.getLength(a);

• Construct new array:

Object a = Array.newInstance(type, length);

Components

• More functionality than a single class

• Reuse and customize in multiple contexts

Page 146: Object Oriented Design and Patterns by Cay S. Horstmann

146

• "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

Page 147: Object Oriented Design and Patterns by Cay S. Horstmann

147

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

Page 148: Object Oriented Design and Patterns by Cay S. Horstmann

148

• Clients use only facade class methods

Facade Pattern

Context

1. A subsystem consists of multiple classes, making it complicated for clients to use

2. Implementor may want to change subsystem classes

3. Want to give a coherent entry point

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)

Page 149: Object Oriented Design and Patterns by Cay S. Horstmann

149

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

Java Naming Conventions

• property = pair of methods public X getPropertyName() public void setPropertyName(X newValue)

• Replace propertyName with actual name

(e.g. getColor/setColor)

• Exception for boolean properties: public boolean isPropertyName()

• Decapitalization hokus-pokus: getColor -> color getURL -> URL

Editing Beans in a Builder Tool

• Use wizard to make empty frame

Page 150: Object Oriented Design and Patterns by Cay S. Horstmann

150

Editing Beans in a Builder Tool

• Add button to frame

• Edit button with property sheet

Page 151: Object Oriented Design and Patterns by Cay S. Horstmann

151

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

Page 152: Object Oriented Design and Patterns by Cay S. Horstmann

152

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

The BeanInfo Interface

Image getIcon(int iconKind) BeanDescriptor getBeanDescriptor() MethodDescriptor[] getMethodDescriptors() PropertyDescriptor[] getPropertyDescriptors() EventSetDescriptor[] getEventSetDescriptors()

Page 153: Object Oriented Design and Patterns by Cay S. Horstmann

153

int getDefaultEventIndex() int getDefaultPropertyIndex() BeanInfo[] getAdditionalBeanInfo()

Removing Spurious Properties

class MyBeanBeanInfo extends SimpleBeanInfo { public PropertyDescriptor[] getPropertyDescriptors() { try { return new PropertyDescriptor[] { new PropertyDescriptor("x", CarBean.class); new PropertyDescriptor("y", CarBean.class); }; } catch (IntrospectionException exception) { return null; } } }

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

Custom Property Editors

• Three kinds of editors

o Text

o Finite set of choices

o Arbitrary painting and editing

• Implement PropertyEditor interface

• Or extend PropertyEditorSupport class

Editing Text Properties

• Convert between your type and String

• Define two methods

public String getAsText() public void setAsText(String s)

Page 154: Object Oriented Design and Patterns by Cay S. Horstmann

154

• Property sheet uses text field

Editing Choice Properties

• Your type has finite set of string choices

• E.g. DrawMode.DRAW, DrawMode.FILL

• String[] getTags() returns array of choices

• Also need to define getAsText/setAsText

• Property sheet uses combo box

Editing Arbitrary Properties

• Your type isn't easily editable as string

• E.g. Color

• Property editor pops up your edit dialog

o boolean supportsCustomEditor() must return true

o Component getCustomEditor() returns dialog

• Property editor can paint current value of your type

o boolean isPaintable() must return true

o void paintValue(Graphics g, Rectangle bounds) paints

Registering Property Editors

• Global setting

PropertyEditorManager.registerEditor(valueClass, editorClass)

• Per-bean setting

In bean info class:

PropertyDescriptor dimensionProperty = new PropertyDescriptor( "dimension", CarBean.class); dimensionProperty.setPropertyEditorClass(DimensionEditor.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

Page 155: Object Oriented Design and Patterns by Cay S. Horstmann

155

Implementing a Property Sheet

• Used for graph framework in chapter 8

• Form shows property names on left, editors on right

Implementing a Property Sheet

• Get bean info for class

• Get properties from bean info

• Obtain property getter/setter methods from property descriptor

• Use these methods to read and write property values

• Each editor is text field, combo box, or button with painted icon

• Clicking on button brings up dialog

• Ch7/propedit/PropertySheet.java

• Ch7/propedit/PropertySheetTest.java

Page 156: Object Oriented Design and Patterns by Cay S. Horstmann

156

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

Page 157: Object Oriented Design and Patterns by Cay S. Horstmann

157

• 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

<applet code="BannerApplet.class" width="300" height="100"> <param name="message" value="Hello, World!"/> <param name="fontname" value="Serif"/> <param name="fontsize" value="64"/>

Page 158: Object Oriented Design and Patterns by Cay S. Horstmann

158

<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

Collections Framework: Interface Types

Page 159: Object Oriented Design and Patterns by Cay S. Horstmann

159

• 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: Classes

• HashSet: a set implementation that uses hashing to locate the set elements

• TreeSet: a sorted set implementation that stores the elements in a balanced

binary tree

• LinkedList and ArrayList: two implementations of the List interface type

Collections Framework

Collection Interface Type

• Collection holds elements in some way

• Different data structures have different storage strategies

boolean add(Object obj) boolean addAll(Collection c) void clear() boolean contains(Object obj) boolean containsAll(Collection c) boolean equals(Object obj) int hashCode() boolean isEmpty() Iterator iterator() boolean remove(Object obj) boolean removeAll(Collection c) boolean retainAll(Collection c) int size() Object[] toArray() Object[] toArray(Object[] a)

Page 160: Object Oriented Design and Patterns by Cay S. Horstmann

160

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

public Object[] toArray() { Object[] result = new Object[size()]; Iterator e = iterator(); for (int i=0; e.hasNext(); i++) 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

Adding a new Class to the Framework

• Use queue from chapter 3

• Supply an iterator (with do-nothing remove method)

• add method always returns true

• Ch8/queue/Queue.java

• Ch8/queue/QueueTest.java

Adding a new Class to the Framework

Page 161: Object Oriented Design and Patterns by Cay S. Horstmann

161

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:

boolean add(int index, Object obj) boolean addAll(int index, Collection c) Object get(int index) int indexOf(Object obj) int lastIndexOf(Object obj) ListIterator listIterator() ListIterator listIterator(int index) Object remove(int index) Object set(int index, int Object) List subList(int fromIndex, int toIndex)

List Iterators

• Indexing

• Bidirectional behavior

• Subtype methods:

Page 162: Object Oriented Design and Patterns by Cay S. Horstmann

162

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)

Page 163: Object Oriented Design and Patterns by Cay S. Horstmann

163

• 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

Graph Editor Framework

• Problem domain: interactive editing of diagrams

• Graph consists of nodes and edges

• Class diagram:

nodes are rectangles

edges are arrows

• Electronic circuit diagram:

nodes are transistors, resistors

edges are wires

Graph Editor Framework

• Traditional approach: programmer starts from scratch for every editor type

• Framework approach: Programmer extends graph, node, edge classes

• Framework handles UI, load/save, ...

• Our framework is kept simple

• Violet uses extension of this framework

User Interface

• Toolbar on top

• Grabber button for selecting nodes/edges

• Buttons for current node/edge type

• Menu

• Drawing area

Page 164: Object Oriented Design and Patterns by Cay S. Horstmann

164

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

Adding Nodes and Edges

• Framework draws toolbar

• How does it know what nodes/edges to draw?

• App gives a list of nodes/edges to framework at startup

• How does app specify nodes/edges?

o Class names? ("Transistor")

o Class objects? (Transistor.class)

o Node, Edge objects? (new Transistor())

Page 165: Object Oriented Design and Patterns by Cay S. Horstmann

165

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

1. Define a prototype interface type that is common to all created objects.

2. Supply a prototype object for each kind of object that the system creates.

3. Clone the prototype object whenever a new object of the given kind is required.

PROTOTYPE Pattern

PROTOTYPE Pattern

Page 166: Object Oriented Design and Patterns by Cay S. Horstmann

166

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

Node Connection Points

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

Page 167: Object Oriented Design and Patterns by Cay S. Horstmann

167

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

Page 168: Object Oriented Design and Patterns by Cay S. Horstmann

168

A Framework Instance

• Ch8/graphed/SimpleGraph.java

• Ch8/graphed/SimpleGraphEditor.java

• Ch8/graphed/CircleNode.java

• Ch8/graphed/LineEdge.java

Generic Framework Code

• Framework frees application programmer from tedious programming

• Framework can do significant work without knowing node/edge types

• Analyze two scenarios

o Add new node

o Add new edge

Add New Node

public void mousePressed(MouseEvent event) { Point2D mousePoint = event.getPoint(); Object tool = toolBar.getSelectedTool(); ... if (tool instanceof Node) { Node prototype = (Node) tool;

Page 169: Object Oriented Design and Patterns by Cay S. Horstmann

169

Node newNode = (Node)prototype.clone(); graph.add(newNode, mousePoint); } ... repaint(); }

Add New Node

Add New Edge

• First check if mouse was pressed inside existing node public Node findNode(Point2D p) { for (int i = 0; i < nodes.size(); i++) { Node n = (Node) nodes.get(i); if (n.contains(p)) return n; } return null; }

Add New Edge

• mousePressed:

o Check if mouse point inside node

o Check if current tool is edge

o Mouse point is start of rubber band • mouseDragged:

o Mouse point is end of rubber band; repaint • mouseReleased:

o Add edge to graph

Page 170: Object Oriented Design and Patterns by Cay S. Horstmann

170

Add New Edge

Enhancing the Framework

• Edit node/edge properties

o Node colors

o Edge styles (solid/dotted)

• Framework enhancement: Edit->Properties menu pops up property dialog

Enhancing the Framework

Page 171: Object Oriented Design and Patterns by Cay S. Horstmann

171

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!

Using the Framework Enhancement

• Add dotted lines

• Define enumerated type LineStyle

• Two instances LineStyle.SOLID, LineStyle.DOTTED

• Add lineStyle property to LineEdge

• LineStyle has method getStroke()

• LineEdge.draw calls getStroke()

• Supply property editor for LineStyle type

• Property editor now edits line style!

Another Framework Instance

• UML Class diagram editor

• "Violet lite"

Page 172: Object Oriented Design and Patterns by Cay S. Horstmann

172

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

Page 173: Object Oriented Design and Patterns by Cay S. Horstmann

173

Multiline String Property Editor

Enhancing the Framework II

• Violet is based on an enhancement of the book's framework

• Adds many options

o graphics export

o grid

o multiple windows

Page 174: Object Oriented Design and Patterns by Cay S. Horstmann

174

• Can add 3 simple graph editor classes to that framework

• App tracks framework evolution at no cost to app programmer

Enhancing the Framework II

Page 175: Object Oriented Design and Patterns by Cay S. Horstmann

175

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

Page 176: Object Oriented Design and Patterns by Cay S. Horstmann

176

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

for (int i = 1; i <= 10; i++) { System.out.println(i + ": " + greeting); Thread.sleep(100); }

• After each printout, sleep for 100 millisec

• All threads should occasionally yield control

• sleep throws InterruptedException

Thread Example

• Ch9/greeting/GreetingProducer.java

• Ch9/greeting/ThreadTest.java

Page 177: Object Oriented Design and Patterns by Cay S. Horstmann

177

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!

Starting Two Threads

Page 178: Object Oriented Design and Patterns by Cay S. Horstmann

178

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

Page 179: Object Oriented Design and Patterns by Cay S. Horstmann

179

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

Page 180: Object Oriented Design and Patterns by Cay S. Horstmann

180

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

Page 181: Object Oriented Design and Patterns by Cay S. Horstmann

181

int i = 1; while (i <= repetitions) { if (!queue.isEmpty()) { Object greeting = queue.removeFirst(); System.out.println(greeting); i++; } Thread.sleep((int)(Math.random() * DELAY)); }

Expected Program Output

1: Hello, World! 1: Goodbye, World! 2: Hello, World! 3: Hello, World! ... 99: Goodbye, World! 100: Goodbye, World!

Why is Output Corrupted?

• Sometimes program gets stuck and doesn't complete

• Can see problem better when turning debugging on queue.setDebug(true);

• Ch9/queue1/ThreadTest.java

• Ch9/queue1/Producer.java

• Ch9/queue1/Consumer.java

• Ch9/queue1/Queue.java

Race Condition Scenario

• First thread calls add and executes

elements[tail] = anObject;

• First thread at end of time slice

• Second thread calls add and executes

elements[tail] = anObject;

tail++;

• Second thread at end of time slice

• First thread executes

tail++;

Race Condition Scenario

Page 182: Object Oriented Design and Patterns by Cay S. Horstmann

182

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) { ... }

Page 183: Object Oriented Design and Patterns by Cay S. Horstmann

183

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

Page 184: Object Oriented Design and Patterns by Cay S. Horstmann

184

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

Page 185: Object Oriented Design and Patterns by Cay S. Horstmann

185

• 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

Pausing and Running the Animation

• Want to pause animation until button is clicked

• Need to coordinate UI thread, animation thread

• Easier to understand coordination with custom object

• Both threads query, manipulate gate

Page 186: Object Oriented Design and Patterns by Cay S. Horstmann

186

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

Pausing and Running the Animation

• compare method checks gate if (gate.isActive()) gate.waitForOpen();

• Button callbacks set gate state

• Ch9/animation2/Gate.java

• Ch9/animation2/AnimationTest.java

Animation Classes

Page 187: Object Oriented Design and Patterns by Cay S. Horstmann

187

Page 188: Object Oriented Design and Patterns by Cay S. Horstmann

188

Object-Oriented Design & Patterns

Cay S. Horstmann

Chapter 10

More Design Patterns

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

Page 189: Object Oriented Design and Patterns by Cay S. Horstmann

189

• Solution: Create an adapter that adapts Icon to Component

• Ch10/adapter/IconAdapter.java

• Ch10/adapter/IconAdapterTest.java

The ADAPTER Pattern

Context

1. You want to use an existing class (adaptee) without modifying it.

2. The context in which you want to use the class requires target interface that is

different from that of the adaptee.

3. The target interface and the adaptee interface are conceptually related.

The ADAPTER Pattern

Solution

1. Define an adapter class that implements the target interface.

2. The adapter class holds a reference to the adaptee. It translates target methods to

adaptee methods.

3. The client wraps the adaptee into an adapter class object.

The ADAPTER Pattern

The ADAPTER Pattern

Page 190: Object Oriented Design and Patterns by Cay S. Horstmann

190

Name in Design

Pattern

Actual Name (Icon->Component)

Adaptee Icon

Target JComponent

Adapter IconAdapter

Client The class that wants to add icons into a container

targetMethod() paintComponent(), getPreferredSize()

adapteeMethod() paintIcon(), getIconWidth(), getIconHeight()

The ADAPTER Pattern

• In stream library

• Input streams read bytes

• Readers read characters

• Non-ASCII encoding: multiple bytes per char

• System.in is a stream

• What if you want to read characters?

• Adapt stream to reader • InputStreamReader

The ADAPTER Pattern

Name in Design Pattern Actual Name (Stream->Reader)

Adaptee InputStream

Target Reader

Adapter InputStreamReader

Client The class that wants to read text from an input stream

targetMethod() read (reading a character)

adapteeMethod() read (reading a byte)

User Interface Actions

• Multiple routes to the same action

• Example: Cut a block of text

o Select Edit->Cut from menu

o Click toolbar button

o Hit Ctrl+X

• Action can be disabled (if nothing is selected)

Page 191: Object Oriented Design and Patterns by Cay S. Horstmann

191

• Action has state

• Action should be an object

User Interface Actions

The Action Interface Type

• Extends ActionListener

• Can be enabled/disabled

• Additional state, including

o Action name

o Icon • helloAction.putValue(Action.NAME, "Hello"); • menu.add(helloAction);

• Extend AbstractAction convenience class

The Action Interface Type

Page 192: Object Oriented Design and Patterns by Cay S. Horstmann

192

Action Example

• Ch10/command/CommandTest.java

• Ch10/command/GreetingAction.java

The COMMAND Pattern

Context

1. You want to implement commands that behave like objects

o because you need to store additional information with commands

o because you want to collect commands.

The COMMAND Pattern

Solution

1. Define a command interface type with a method to execute the command.

2. Supply methods in the command interface type to manipulate the state of

command objects.

3. Each concrete command class implements the command interface type.

4. To invoke the command, call the execute method.

Page 193: Object Oriented Design and Patterns by Cay S. Horstmann

193

The COMMAND Pattern

The COMMAND Pattern

Name in Design Pattern Actual Name (Swing actions)

Command Action

ConcreteCommand subclass of AbstractAction

execute() actionPerformed()

state name and icon

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!

The FACTORY METHOD Pattern

Context

Page 194: Object Oriented Design and Patterns by Cay S. Horstmann

194

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.

The FACTORY METHOD Pattern

Solution

1. Define a creator type that expresses the commonality of all creators.

2. Define a product type that expresses the commonality of all products.

3. Define a method, called the factory method, in the creator type.

The factory method yields a product object.

4. Each concrete creator class implements the factory method so that it returns an

object of a concrete product class.

The FACTORY METHOD Pattern

The FACTORY METHOD Pattern

Name in Design Pattern Actual Name (iterator)

Creator Collection

ConcreteCreator A subclass of Collection

factoryMethod() iterator()

Product Iterator

ConcreteProduct A subclass of Iterator (which is often anonymous)

Page 195: Object Oriented Design and Patterns by Cay S. Horstmann

195

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

Deferred Image Loading

Deferred Image Loading

• Normally, programmer uses image for label: JLabel label = new JLabel(new ImageIcon(imageName));

• Use proxy instead: JLabel label = new JLabel(new ImageProxy(imageName));

Page 196: Object Oriented Design and Patterns by Cay S. Horstmann

196

• 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

The PROXY Pattern

Context

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.

The PROXY Pattern

Solution

1. Define a proxy class that implements the subject interface type.

The proxy holds a reference to the real subject, or otherwise knows how to locate

it.

2. The client uses a proxy object.

3. Each proxy method invokes the same method on the real subject and provides the

necessary modifications.

The PROXY Pattern

Page 197: Object Oriented Design and Patterns by Cay S. Horstmann

197

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

Random Number Generator Singleton

public class SingleRandom { private SingleRandom() { generator = new Random(); } public void setSeed(int seed) { generator.setSeed(seed); } public int nextInt() { return generator.nextInt(); }

Page 198: Object Oriented Design and Patterns by Cay S. Horstmann

198

public static SingleRandom getInstance() { return instance; } private Random generator; private static SingleRandom instance = new SingleRandom(); }

The SINGLETON Pattern

Context

1. All clients need to access a single shared instance of a class.

2. You want to ensure that no additional instances can be created accidentally.

The SINGLETON Pattern

Solution

1. Define a class with a private constructor.

2. The class constructs a single instance of itself.

3. Supply a static method that returns a reference to the single instance.

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

Page 199: Object Oriented Design and Patterns by Cay S. Horstmann

199

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)

Page 200: Object Oriented Design and Patterns by Cay S. Horstmann

200

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

Page 201: Object Oriented Design and Patterns by Cay S. Horstmann

201

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

Page 202: Object Oriented Design and Patterns by Cay S. Horstmann

202

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

Double Dispatch Example

The VISITOR Pattern

Context

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.

The VISITOR Pattern

Solution

Page 203: Object Oriented Design and Patterns by Cay S. Horstmann

203

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.

The VISITOR Pattern

The VISITOR Pattern

Name in Design Pattern Actual Name (file system visitor)

Element FileSystemNode

ConcreteElement FileNode, DirectoryNode

Visitor FileSystemVisitor

ConcreteVisitor PrintVisitor

Other Design Patterns

• Abstract Factory

Page 204: Object Oriented Design and Patterns by Cay S. Horstmann

204

• Bridge

• Builder

• Chain of Responsibility

• Flyweight

• Interpreter

• Mediator

• Memento

• State

Conclusion: What You Learned

1. Object-oriented design

The design methodology

CRC cards and UML diagrams

Design patterns

2. Advanced Java

Interface types, polymorphism, and inheritance

Inner classes

Reflection

Multithreading

Collections

3. User interface programming

Building Swing applications

Event handling

Graphics programming