


























Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
A set of slides from a design patterns course, focusing on behavioural patterns and iterators. It covers the concept of behavioural patterns, which deal with cooperation between objects, and iterators, which allow abbreviated foreach loops in java. The document also includes java code examples for iterating through a treeset and using the iterable interface.
Typology: Slides
1 / 34
This page cannot be seen from the preview
Don't miss anything!



























Ian Holyer
Ian Holyer
●
Yet again, here is the "periodic table" of patterns: Yet again, here is the "periodic table" of patterns:
●
The behavioural patterns we will look at are: The behavioural patterns we will look at are:
●
iterator (for running though sets, lists, ...)
●
observer (this is the model-view GUI pattern)
●
state (use classes instead of switch statements)
●
strategy (almost the same as state)
●
command (representing operations as objects)
●
double dispatch (using two objects to find a method)
●
visitor (operations on complex tree data structures)
●
There are lots more we won't look at There are lots more we won't look at
●
This is very common in the Java libraries This is very common in the Java libraries
●
The idea is that lists, sets, hash tables, trees, and any other
The idea is that lists, sets, hash tables, trees, and any other
collections or composite data structures you can think of, collections or composite data structures you can think of,
should allow you to loop through their items in a standard should allow you to loop through their items in a standard
way without exposing any of their internal details way without exposing any of their internal details
●
In addition, it can be useful for an iterator to be "live", In addition, it can be useful for an iterator to be "live",
allowing items to be inserted/updated/deleted without allowing items to be inserted/updated/deleted without
affecting the traversal (and without making a copy of the affecting the traversal (and without making a copy of the
structure)
structure)
●
We will use Java's Iterator notation directly We will use Java's Iterator notation directly
●
Some sources describe Enumeration, which is "obsolete"
Some sources describe Enumeration, which is "obsolete"
●
Here's the code for iterating through a TreeSet Here's the code for iterating through a TreeSet
Set
...
Iterator
while (seq.hasNext())
{
Item item = seq.next();
...
if (...) seq.remove();
}
Set
...
Iterator
while (seq.hasNext())
{
Item item = seq.next();
...
if (...) seq.remove();
}
●
While iterating, the set can be changed While iterating, the set can be changed only only through the through the
iterator, iterator, not not via the via the items items variable, or by other threads variable, or by other threads
●
The The Iterable Iterable interface allows abbreviated interface allows abbreviated foreach foreach
loops loops in Java 5, which hide the iterator details: in Java 5, which hide the iterator details:
Set
...
for (Item item : items)
{ ...
}
Set
...
for (Item item : items)
{ ...
}
●
This also works on arrays, and anything you define This also works on arrays, and anything you define
yourself which implements yourself which implements Iterable Iterable
●
You can return a collection from a method as an You can return a collection from a method as an
Iterable, instead of wrapping it to make it immutable
Iterable, instead of wrapping it to make it immutable
●
You have to use the long form for deletion, indexing etc. You have to use the long form for deletion, indexing etc.
●
The usual way in which two objects communicate is for The usual way in which two objects communicate is for
one to call a method in the other:
one to call a method in the other:
class Caller class Called
...Called object; { void method()
...object.method(); { ...
●
But what if the caller class is in a library? But what if the caller class is in a library?
●
Then it can't know about the called class when it is
Then it can't know about the called class when it is
created, so it can't declare the called object
created, so it can't declare the called object
●
This problem occurs throughout the Java graphics This problem occurs throughout the Java graphics
libraries, where it is known as the
libraries, where it is known as the model-view
model-view pattern or
pattern or
listener
listener pattern
pattern (and deals with both logic classes calling
(and deals with both logic classes calling
GUI objects, and vice versa) GUI objects, and vice versa)
●
Here's a UML diagram for the observer pattern Here's a UML diagram for the observer pattern
Observable
observers
add(Observer)
notify(State)
Observer
Called
update(State)
Caller
for (o in observers)
o.update(state)
0..*
●
The Observable class in The Observable class in java.util java.util holds a collection holds a collection
of observers and provides methods addObserver and of observers and provides methods addObserver and
notifyObservers notifyObservers
●
You are expected to extend it
You are expected to extend it
●
The class also has a boolean "changed" flag and a The class also has a boolean "changed" flag and a
setChanged() method, and notifyObservers() is really setChanged() method, and notifyObservers() is really
"notify
"notify if
if changed
changed , and reset the changed flag"
, and reset the changed flag"
●
Then you can call notify frequently, and separately call Then you can call notify frequently, and separately call
setChanged when you want it to be activated setChanged when you want it to be activated
●
The Observer interface just has an update method
The Observer interface just has an update method
●
The UML for Observable/Observer is: The UML for Observable/Observer is:
Observable
observers
addObserver(Observer)
setChanged()
notifyObservers(Object)
Observer
Called
update(Observable, Object)
Caller
●
Differences: Observable is a class not an interface, there
Differences: Observable is a class not an interface, there
is a changed flag, and two arguments are passed
is a changed flag, and two arguments are passed
0..*
ASIDE on Patterns 3, slide 16
both directions (model calls view or view calls model)
GUI object which displays it on the screen, and those
words appear in the library class names
"observable" and some data object is the "observer"
"observable" (so Document is a GUI class!) and
changes to the document model are notified to any GUI
views that want to update their displays
program notified, if you want
●
The state design pattern is used when you find yourself The state design pattern is used when you find yourself
writing or wanting to write something like:
writing or wanting to write something like:
class Thing
{ int state, INITIAL=0, NORMAL=1, ...;
void method1()
{ if (state == INITIAL) ...
else if (state == NORMAL) ...
...
}
void method2()
{ if (state == INITIAL) ...
else if (state == NORMAL) ...
...
}
class Thing
{ int state, INITIAL=0, NORMAL=1, ...;
void method1()
{ if (state == INITIAL) ...
else if (state == NORMAL) ...
...
}
void method2()
{ if (state == INITIAL) ...
else if (state == NORMAL) ...
...
}
●
Now the code delegates to the state object: Now the code delegates to the state object:
class Thing
{
State state = ...;
void method1()
{
state.method1();
}
void method2()
{
state.method2();
}
}
class Thing
{
State state = ...;
void method1()
{
state.method1();
}
void method2()
{
state.method2();
}
}
●
This is extremely similar: suppose you want to choose This is extremely similar: suppose you want to choose
between several strategies according to circumstance
between several strategies according to circumstance
●
You want to use insertion sort if there are a few items, You want to use insertion sort if there are a few items,
quicksort if there are a lot, mergesort for stability... quicksort if there are a lot, mergesort for stability...
●
Then you regard your object that does the sorting as "in
Then you regard your object that does the sorting as "in
the insertion sort state" or "in the quicksort state" so you the insertion sort state" or "in the quicksort state" so you
have a sorter "state" object and delegate the sort method have a sorter "state" object and delegate the sort method
to it to it
●
When you look at it like that, the UML diagram is
When you look at it like that, the UML diagram is
identical, except that states are called strategies identical, except that states are called strategies
●
An example in the Java libraries is LayoutManagers: a
An example in the Java libraries is LayoutManagers: a
GUI container has a LayoutManager strategy object
GUI container has a LayoutManager strategy object