0% found this document useful (0 votes)
27 views96 pages

L24 BehavioralDesignPatterns

The document discusses behavioral design patterns in software development, focusing on patterns that facilitate communication between objects. Key patterns covered include Strategy, Template Method, Observer, Command, Iterator, and State patterns, along with their implementations and examples. The document emphasizes the importance of flexibility and reusability in software design through these patterns.

Uploaded by

mdshahed1438
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
27 views96 pages

L24 BehavioralDesignPatterns

The document discusses behavioral design patterns in software development, focusing on patterns that facilitate communication between objects. Key patterns covered include Strategy, Template Method, Observer, Command, Iterator, and State patterns, along with their implementations and examples. The document emphasizes the importance of flexibility and reusability in software design through these patterns.

Uploaded by

mdshahed1438
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 96

Behavioral Design Patterns

Paul Fodor
CSE316: Fundamentals of Software
Development
Stony Brook University
[Link]
Behavioral Design Patterns
Design patterns that identify common
communication patterns between
objects and realize these patterns.
 they increase the flexibility in
carrying out communication

2
(c) Paul Fodor & O'Reilly Media
Behavioral Design Patterns
 Strategy pattern: algorithms can be selected on the fly
 Template method pattern: describes the program skeleton of a
program
 Observer pattern: objects register to observe an event that may
be raised by another object (i.e., Event Listener)
 Command pattern: command objects encapsulate an action and
its parameters
 Iterator pattern: iterators are used to access the elements of an
aggregate object sequentially without exposing its underlying
representation
 State pattern: a clean way for an object to partially change its type
at runtime
3
(c) Paul Fodor & O'Reilly Media
Common Design Patterns
Creational Structural Behavioral
• Factory • Decorator • Strategy
• Singleton • Adapter • Template
• Builder • Facade • Observer
• Prototype • Flyweight • Command
• Bridge • Iterator
• State

4
Textbook: Head First Design Patterns
(c) Paul Fodor & O'Reilly Media
The Strategy Pattern
 Defines a family of algorithms, encapsulates each one, and
makes them interchangeable
 lets the algorithm vary independently from the clients that use
them
 An algorithm in a box
 place essential steps for an algorithm in a strategy interface
 different methods represent different parts of the algorithm
 classes implementing this interface customize methods
 Classes can be composed (HAS-A) of the interface type
 the interface type is the apparent type
 the actual type can be determined at run-time

5
(c) Paul Fodor & O'Reilly Media
The Strategy Pattern Example

6
(c) Paul Fodor & O'Reilly Media
abstract class Duck {
FlyBehaviour flyBehaviour;
QuackBehaviour quackBehaviour;
public void fly() {
[Link] [Link]();
}
public void quack() {
[Link]();
}
}
interface FlyBehaviour {
void fly();
}
class FlyWithWings implements FlyBehaviour {
public void fly() {
[Link]("Flying with wings ...");
}
}
class FlyNoWay implements FlyBehaviour {
public void fly() {
[Link]("Cannot Fly.");
}
}
interface QuackBehaviour {
void quack();
}
class Quack implements QuackBehaviour {
public void quack() {
[Link]("Quack quack ...");
7 }
(c) Paul Fodor & O'Reilly Media
}
class RubberQuack implements QuackBehaviour {
public void quack() {
[Link]("Quick quack ...");
}
}
class MallardDuck extends Duck{
public MallardDuck() {
[Link] = new FlyWithWings();
[Link] = new Quack();
}
}
class RubberDuck extends Duck{
public RubberDuck() {
[Link] = new FlyNoWay();
[Link] = new RubberQuack();
}
}
public class StrategyExample {
public static void main(String[] args) {
Duck duck = new MallardDuck();
[Link]();
[Link]();

duck = new RubberDuck();


[Link]();
[Link]();
8 } (c) Paul Fodor & O'Reilly Media
}
The Strategy Pattern
 We are using composition instead of inheriting
their behavior: the ducks get their behavior by
being composed with the right behavior object.
 The HAS-A relationship can be better than IS-A
 In the example, each duck has a FlyBehavior and a
QuackBehavior to which it delegates flying and
quacking.
 It also allows to change the behavior at runtime as
long as the object implements the correct behavior
interface.
9
(c) Paul Fodor & O'Reilly Media
/** [Link] using the strategy pattern
* The classes that implement a concrete strategy should implement Strategy
* interface.
* The Context class uses this to call the concrete strategy. */
interface Strategy {
int execute(int a, int b);
}

/** Implements the algorithm using the strategy interface */


class Add implements Strategy {
public int execute(int a, int b) {
[Link]("Called Add's execute()");
return a + b; // Do an addition with a and b
}
}

class Subtract implements Strategy {


public int execute(int a, int b) {
[Link]("Called Subtract's execute()");
return a - b; // Do a subtraction with a and b
}
}

class Multiply implements Strategy {


public int execute(int a, int b) {
[Link]("Called Multiply's execute()");
return a * b; // Do a multiplication with a and b
}
}
10
(c) Paul Fodor & O'Reilly Media
// Configured with a ConcreteStrategy object and maintains
// a reference to a Strategy object
class Context {
private Strategy strategy;
public Context(Strategy strategy) {
[Link] = strategy;
}
public int executeStrategy(int a, int b) {
return [Link](a, b);
}
}

public class Calculator {


public static void main(String[] args) {
Context context;
// Three contexts following different strategies
context = new Context(new Add());
int resultA = [Link](3,4);
[Link]("Result A : " + resultA );

context = new Context(new Subtract());


int resultB = [Link](3,4);
[Link]("Result B : " + resultB );

context = new Context(new Multiply());


int resultC = [Link](3,4);
[Link]("Result C : " + resultC );
}
}
11
(c) Paul Fodor & O'Reilly Media
Strategy Patterns in the Java API
• LayoutManagers interface in SWING
– describes how to arrange components:
• components added to or removed from the container.
• automatic resizing and position the components it
manages
public interface LayoutManager {
void addLayoutComponent(String name, Component comp);
void removeLayoutComponent(Component comp);
Dimension preferredLayoutSize(Container parent);
Dimension minimumLayoutSize(Container parent);
void layoutContainer(Container parent);
}

12
(c) Paul Fodor & O'Reilly Media
Containers use LayoutManagers
• Composition / at runtime:
public class Container extends Component {
private List<Component> component;
private LayoutManager layoutMgr;

public void setLayout(LayoutManager mgr) {
layoutMgr = mgr;
}
}

13
(c) Paul Fodor & O'Reilly Media
Dynamic interchange
• Interchangeable layout algorithms:
public void initGUI() {
panel = new JPanel();
[Link](new FlowLayout());
// [Link](new VBoxLayout());
[Link](new JButton("Ok"));
[Link](new JButton("Cancel"));
}

14
(c) Paul Fodor & O'Reilly Media
Common Design Patterns
Creational Structural Behavioral
• Factory • Decorator • Strategy
• Singleton • Adapter • Template
• Builder • Facade • Observer
• Prototype • Flyweight • Command
• Bridge • Iterator
• State

15
Textbook: Head First Design Patterns
(c) Paul Fodor & O'Reilly Media
Template Method Pattern
 A template for a general algorithm
 Defines the skeleton of an algorithm in a
method, deferring some steps to subclasses.
Lets subclasses redefine certain steps of an
algorithm without changing the algorithm’s
structure.

16
(c) Paul Fodor & O'Reilly Media
Template Method Pattern
 Example: Starbuzz beverages are similar
 Coffee:
 (1) Boil some water
 (2) Brew coffee in boiling water
 (3) Pour coffee in cup
 (4) Add sugar and milk
 Tea: // eliminate code duplication
 (1) Boil some water
 (2) Steep tea in boiling water
 (3) Pour tea in cup
17  (4) Add lemon
(c) Paul Fodor & O'Reilly Media
Template Method Pattern

18
(c) Paul Fodor & O'Reilly Media
Template Method Pattern

19
(c) Paul Fodor & O'Reilly Media
20
(c) Paul Fodor & O'Reilly Media
21
(c) Paul Fodor & O'Reilly Media
22
(c) Paul Fodor & O'Reilly Media
Template Method Pattern

23
(c) Paul Fodor & O'Reilly Media
Template Method Pattern

24
(c) Paul Fodor & O'Reilly Media
What’s a hook?
 A method only declared in the abstract class
 only given an empty or default implementation

 Gives subclasses the ability to "hook into" the


algorithm at various points, if they wish
 a subclass is also free to ignore the hook.
25
(c) Paul Fodor & O'Reilly Media
26
(c) Paul Fodor & O'Reilly Media
abstract class CaffeineBeverage { // [Link]
public final void prepareRecipe() {
boilWater();
brew();
pourInCup();
addCondiments();
hook();
}
void boilWater() {
[Link]("Boiling water ...");
hookWaterHasBoiled();
}
void pourInCup() {
[Link]("Pour fluid in cup.");
}
abstract void brew();
abstract void addCondiments();
void hook(){}
void hookWaterHasBoiled(){}
}
class Coffee extends CaffeineBeverage {
@Override
void brew() {
[Link]("Brew/filter the coffee ...");
}
@Override
void addCondiments() {
[Link]("Add milk and sugar to the coffeee.");
27 }
(c) Paul Fodor & O'Reilly Media
@Override
void hook() {
[Link]("Did you like the coffee?");
}
}
class Tea extends CaffeineBeverage {
@Override
void brew() {
[Link]("Put teabag in the water.");
}
@Override
void addCondiments() {
[Link]("Add sugar and honey to the tea");
}
@Override
void hookWaterHasBoiled() {
[Link]("The tea water is boiling!!!");
}
}
public class Starbuzz {
public static void main(String[] args) {
CaffeineBeverage beverage = new Coffee();
[Link]();

beverage = new Tea();


[Link]();
}
}

28
(c) Paul Fodor & O'Reilly Media
Strategy vs. Template Method
 What’s the difference?
 Strategy
encapsulate interchangeable behaviors and
use delegation to decide which behavior to
use
 Template Method
subclasses decide how to implement steps
in an algorithm
29
(c) Paul Fodor & O'Reilly Media
/** An abstract class that is common to several games in which players play
* against the others, but only one is playing at a given time.
*/
abstract class Game {
protected int playersCount;
abstract void initializeGame();
abstract void makePlay(int player);
Play
abstract boolean endOfGame();
abstract void printWinner();
/* A template method: */
template
public final void playOneGame(int playersCount) {
[Link] = playersCount;
initializeGame();
example
int j = 0;
while (!endOfGame()) {
makePlay(j);
j = (j + 1) % playersCount;
}
printWinner();
}
}
//Now we can extend this class in order
//to implement actual games:
class Monopoly extends Game {
/* Implementation of necessary concrete methods */
void initializeGame() {
// Initialize players
// Initialize money
30 }
(c) Paul Fodor & O'Reilly Media
void makePlay(int player) {
// Process one turn of player
}
boolean endOfGame() {
// Return true if game is over
// according to Monopoly rules
}
void printWinner() {
// Display who won
}
/* Specific declarations for the Monopoly game. */
}
class Chess extends Game {
/* Implementation of necessary concrete methods */
void initializeGame() {
// Initialize players
// Put the pieces on the board
}
void makePlay(int player) {
// Process a turn for the player
}
boolean endOfGame() {
// Return true if in Checkmate or
// Stalemate has been reached
}
void printWinner() {
// Display the winning player
}
/* Specific declarations for the chess game. */
31 }
(c) Paul Fodor & O'Reilly Media
Common Design Patterns
Creational Structural Behavioral
• Factory • Decorator • Strategy
• Singleton • Adapter • Template
• Builder • Facade • Observer
• Prototype • Flyweight • Command
• Bridge • Iterator
• State

32
Textbook: Head First Design Patterns
(c) Paul Fodor & O'Reilly Media
The Observer Pattern
 Defines a one-to-many dependency between
objects so that when one object changes state, all of
its dependents are notified and updated automatically
 Where have we seen this?
 in our GUI
 State Manager class maintains application's state
 call methods to change app's state
 app's state change forces update of GUI

33
(c) Paul Fodor & O'Reilly Media
The Observer Pattern
 Example: a WeatherData
object is "observed" by
multiple apps.

34
(c) Paul Fodor & O'Reilly Media
import [Link]; // [Link]
import [Link];

class Observable {
List<Observer> observers = new ArrayList<Observer>();
void publish(Object data) {
for (Observer obs : [Link]) {
[Link](this,data);
}
}
public void subscribe(Observer obs) {
[Link](obs);
}
public void unsubscribe(Observer obs) {
[Link](obs);
}
}

interface Observer {
void update(Observable observable, Object object);
}

class WeatherData extends Observable {


int temperature;
public void update(int newTemperature) {
[Link] = newTemperature;
[Link](new Integer(temperature));
}
}
35
(c) Paul Fodor & O'Reilly Media
class WeatherStation implements Observer {
public WeatherStation(WeatherData obs) {
[Link](this);
}
@Override
public void update(Observable observable, Object object) {
if (observable instanceof WeatherData
&& object instanceof Integer) {
Integer temp = (Integer) object;
[Link]("Station: temperature is " + temp);
}
}
}

public class ObserverWeather {


public static void main(String[] args) {
WeatherData data = new WeatherData();

WeatherStation station1 = new WeatherStation(data);


WeatherStation station2 = new WeatherStation(data);
[Link](40);

[Link](station1);
[Link]("deleted one");

[Link](35);
}
}

36
(c) Paul Fodor & O'Reilly Media
37
(c) Paul Fodor & O'Reilly Media
38
(c) Paul Fodor & O'Reilly Media
The Observer Pattern

39
(c) Paul Fodor & O'Reilly Media
40
(c) Paul Fodor & O'Reilly Media
41
(c) Paul Fodor & O'Reilly Media
JTrees
 Used to display a hierarchical structure
 File structure, browsing history, etc…

42
(c) Paul Fodor & O'Reilly Media
Editing
• To edit the tree, you must go through the model:
JTree tree = new JTree(…);
TreeModel model = [Link]();

// Insert Node
[Link](…

// Remove Node
[Link](…

// Change Node
[Link](…

// UPDATING THE MODEL WILL NOW AUTOMATICALLY UPDATE


// THE VIEW (JTree) THANKS TO MVC!

43
(c) Paul Fodor & O'Reilly Media
Complex Controls have their own States
 Tables, trees, lists, combo boxes, etc.
 data is managed separately from the view
 when the state changes, the view is updated
 This is called MVC
 Model
 View
 Controller
 MVC employs the Observer Pattern
44
(c) Paul Fodor & O'Reilly Media
MVC employs the Observer Pattern
 Model
 data structure, no visual representation
 notifies views when something interesting happens
 View / Observer
 visual representation
 views attach themselves to model in order to be notified
 Controller
 event handler
 listeners that are attached to view in order to be notified of user interaction
(or otherwise)
 MVC Interaction
 controller updates model
 model tells view that data has changed
45
 view redrawn (c) Paul Fodor & O'Reilly Media
Controller Model View

updateData

notify

repaint

return

return

46
(c) Paul Fodor & O'Reilly Media
MVC Architecture
The model passes its
data to the view for
rendering
Model View

The view determines


The controller updates which events are passed
the model based on to the controller
events received Controller

47
(c) Paul Fodor & O'Reilly Media
GUIs love MVC
Model View Controller
• ComboBoxModel – JComboBox - ItemListener
• ListModel – JList - ListSelectionListener
• TableModel - JTable - CellEditorListener
• TreeModel - JTree - TreeSelectionListener

48
(c) Paul Fodor & O'Reilly Media
Common Design Patterns
Creational Structural Behavioral
• Factory • Decorator • Strategy
• Singleton • Adapter • Template
• Builder • Facade • Observer
• Prototype • Flyweight • Command
• Bridge • Iterator
• State

49
Textbook: Head First Design Patterns
(c) Paul Fodor & O'Reilly Media
Command Abstraction
 For many GUIs, a single function may be triggered by
many means (e.g., keystroke, menu, button, etc…)
 we want to link all similar events to the same listener
 The information concerning a command can be
abstracted to a separate command object
 The Command Pattern Common Approach:
 specify a String for each command
 have listener respond to each command differently
 ensures commands are handled in a uniform way
 commands can be specified inside a text file
50
(c) Paul Fodor & O'Reilly Media
• Suppose I wanted to create
a simple GUI:
Example
– 1 colored panel
– 2 buttons, yellow & red
– 2 menu items, yellow & red
– clicking on the buttons or
menu items changes the
color of the panel
• Since the buttons & the
menu items both perform
the same function, they
should be tied to the same
commands
– I could even add popup
51
menu items or other means
to change the colors (c) Paul Fodor & O'Reilly Media
[Link].*;
[Link].*;
[Link].*;
publicclass ColorCommandFrame extends JFrame
implements ActionListener {
private Toolkit tk = [Link]();
private ImageIcon yellowIcon
= new ImageIcon([Link]("yellow_bullet.bmp"));
private ImageIcon redIcon
= new ImageIcon([Link]("red_bullet.bmp"));

private JPanel coloredPanel = new JPanel();


private JButton yellowButton = new JButton(yellowIcon);
private JButton redButton = new JButton(redIcon);

private JMenuBar menuBar = new JMenuBar();


private JMenu colorMenu = new JMenu("Color");
private JMenuItem yellowMenuItem = new JMenuItem(yellowIcon);
private JMenuItem redMenuItem = new JMenuItem(redIcon);

private JPopupMenu popupMenu = new JPopupMenu();


private JMenuItem yellowPopupItem = new JMenuItem(yellowIcon);
private JMenuItem redPopupItem = new JMenuItem(redIcon);

private static final String YELLOW_COMMAND = "YELLOW_COMMAND";


private static final String RED_COMMAND = "RED_COMMAND";
52
(c) Paul Fodor & O'Reilly Media
public ColorCommandFrame() {
super("ColorCommandFrame1");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setExtendedState(JFrame.MAXIMIZED_BOTH);
initButtons();
initPopupMenu();
initMenu();
}

public void initButtons() {


[Link](YELLOW_COMMAND);
[Link](RED_COMMAND);
[Link](this);
[Link](this);
[Link](yellowButton);
[Link](redButton);
Container contentPane = getContentPane();
[Link](coloredPanel);
}

53
(c) Paul Fodor & O'Reilly Media
public void initPopupMenu() {
[Link](YELLOW_COMMAND);
[Link](RED_COMMAND);
[Link](this);
[Link](this);
[Link](yellowPopupItem);
[Link](redPopupItem);
[Link](new MouseAdapter() {
public void mousePressed(MouseEvent e) {
maybeShowPopup(e);
}
public void mouseReleased(MouseEvent e) {
maybeShowPopup(e);
}
private void maybeShowPopup(MouseEvent e) {
if ([Link]()) {
[Link]([Link](),[Link](),[Link]());
}
}
});
54 } (c) Paul Fodor & O'Reilly Media
public void initMenu() {
[Link](YELLOW_COMMAND);
[Link](RED_COMMAND);
[Link](this);
[Link](this);
[Link](yellowMenuItem);
[Link](redMenuItem);
[Link](colorMenu);
setJMenuBar(menuBar);
}
public void actionPerformed(ActionEvent ae) {
String command = [Link]();
if ([Link](YELLOW_COMMAND))
[Link]([Link]);
else if ([Link](RED_COMMAND))
[Link]([Link]);
}
public static void main(String[] args) {
ColorCommandFrame x = new ColorCommandFrame();
[Link](true);
55 }
(c) Paul Fodor & O'Reilly Media
}
interface Command { // [Link]
void execute();
}
class GarageDoor {
private boolean open = false;
public void open() {
[Link] = true;
}
public void close() {
[Link] = false;
}
public void showStatus() {
[Link]("The door is "+[Link]);
}
}
class GarageDoorOpenCommand implements Command {
private GarageDoor garageDoor;
public GarageDoorOpenCommand(GarageDoor door) {
[Link] = door;
}
@Override
public void execute() {
[Link]();
[Link]();
56 }
(c) Paul Fodor & O'Reilly Media
}
class Light {
private boolean on = false;
public void on() {
[Link] = true;
}
public void off() {
[Link] = false;
}
public void toggle() {
[Link] = ![Link];
}
public void showStatus() {
[Link]("The light is "+[Link]);
}
}
class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
[Link] = light;
}
@Override
public void execute() {
[Link]();
[Link]();
57 }
(c) Paul Fodor & O'Reilly Media
}
class SimpleRemoteControl {
private Command command;
public void setCommand(Command command) {
[Link] = command;
}
public void buttonPressed() {
[Link]();
}
}
public class CommandExample {
public static void main(String[] args) {
SimpleRemoteControl control =
new SimpleRemoteControl();
[Link](
new LightOnCommand(new Light()));
[Link]();
[Link](new GarageDoorOpenCommand(
new GarageDoor()));
[Link](); Output:
} The light is true
}
58
(c) Paul Fodor & O'Reilly Media
The door is true
Common Design Patterns
Creational Structural Behavioral
• Factory • Decorator • Strategy
• Singleton • Adapter • Template
• Builder • Facade • Observer
• Prototype • Flyweight • Command
• Bridge • Iterator
• State

59
Textbook: Head First Design Patterns
(c) Paul Fodor & O'Reilly Media
The Iterator Pattern
 The iterator pattern is a design pattern in which an
iterator is used to traverse a container and access
the container's elements: "you have to perform some
operation on a sequence of elements in a given data
structure"
 it decouples algorithms from containers,
 the iterator object will maintain the state of the
iteration, keeping track of the current item and
having a way of identifying what elements are
next to be iterated.
60
(c) Paul Fodor & O'Reilly Media
The Iterator Pattern
• An Iterator produces proper elements for processing
• Using an Iterator must be simple
– they’re all used in the same way
• E.g. update() all elements of List list:
Iterator it;
for (it=[Link](); [Link](); )
[Link]().update();

• Makes iteration through elements of a set "higher level"


• Separates the production of elements for iteration from the
operation at each step in the iteration.

61
(c) Paul Fodor & O'Reilly Media
The Iterator Pattern
• Common Classes using Iterators in Java API
– Vector, ArrayList, etc …
– I/O streams work like Iterators
– StringTokenizer

• Iterator is a design pattern that is encountered very often.


– Problem: Defining an Iterator may be complex
– Solution: The COLLECTION is represented in some data structure
(list, array, hashtable, etc.)

62
(c) Paul Fodor & O'Reilly Media
[Link]
public interface Iterator {
// Returns true if there are more
// elements to iterate over; false
// otherwise
public boolean hasNext();

// If there are more elements to


// iterate over, returns the next one.
// Modifies the state "this" to record
// that it has returned the element.
// If no elements remain, throw
// NoSuchElementException.
public Object next()
throws NoSuchElementException;

public void remove();


} (c) Paul Fodor & O'Reilly Media
Iterator vs. Enumeration
• Java provides another interface Enumeration for
iterating over a collection.
• Iterator is
– newer (since JDK 1.2)
– has shorter method names
– has a remove() method to remove elements from a collection
during iteration
• Iterator Enumeration
hasNext() hasMoreElements()
next() nextElement()
remove() -
• Iterator is recommended for newer implementations.
(c) Paul Fodor & O'Reilly Media
Example Loop controlled by next()
private Payroll payroll = new Payroll();
...
public void decreaseAllPayroll(){ //by 10%
Iterator it = [Link]();
while ([Link]()) {
Employee e = (Employee)[Link]();
double salary = [Link]();
[Link](salary*.9);
}
}

(c) Paul Fodor & O'Reilly Media


Implementing an Iterator
public class Payroll {
private Employee[] employees;
private int num_employees;
...
// An iterator to loop through all Employees
public Iterator getIterator() {
return new EmplGen();
}
...
private class EmplGen implements Iterator {
// see next slide
...
}
}
(c) Paul Fodor & O'Reilly Media
Implementing an Iterator
private class EmplGen implements Iterator {
private int n = 0; state of iteration
captured by index n
public boolean hasNext() {
returns true if there
return n < num_employees;
is an element left
}
to iterate over
public Object next() throws NoSuchElementException {
Object obj;
if (n < num_employees) {
obj = employees[n]; returns the next
n++; element in the
return obj; iteration sequence
}
else throw new NoSuchElementException
("No More Employees");
}

(c) Paul Fodor & O'Reilly Media


Implementing an Iterator
public Object remove(){
Object obj;
if (n < num_employees) {
obj = employees[n];
// shift left all the elements from n+1…num_employees
for(int i=n+1; i<num_employees; i++)
employees[i-1] = employees[i];
num_employees--;
return obj;
}
else
throw new NoSuchElementException("No More Employees");
}
}

(c) Paul Fodor & O'Reilly Media


69
(c) Paul Fodor & O'Reilly Media
The Iterator Pattern
Example: Pancake House and Diner Merger (they use different
internal data structures: array vs. ArrayList

70
(c) Paul Fodor & O'Reilly Media
import [Link]; // [Link]
import [Link];
import [Link];

interface Menu<E> {
public Iterator<E> getIterator();
}

class PancakeHouseMenu<E> implements Menu<E> {


private List<E> food;

public PancakeHouseMenu() {
food = new ArrayList<E>();
}

public void addFood(E food) {


[Link](food);
}

public PancakeHouseMenuIterator<E> getIterator(){


return new PancakeHouseMenuIterator<E>(food);
}
}71 (c) Paul Fodor & O'Reilly Media
class PancakeHouseMenuIterator<E> implements Iterator<E> {
private List<E> food;
private int position;
public PancakeHouseMenuIterator(List<E> food) {
[Link] = food;
}
@Override
public boolean hasNext() {
if(position < [Link]() && [Link](position)!=null){
return true;
} else {
return false;
}
}
@Override
public E next() {
return [Link](position++);
}
@Override
public void remove() {
[Link](position);
}
}72 (c) Paul Fodor & O'Reilly Media
class DinerMenu<E> implements Menu<E> {
private E[] food;
int size = 0;

public DinerMenu() {
food = (E[])(new Object[10]);
}

public void addFood(E food) {


[Link][size++] = food;
}

public DinerMenuIterator<E> getIterator(){


return new DinerMenuIterator<E>(food);
}
}

73
(c) Paul Fodor & O'Reilly Media
class DinerMenuIterator<E> implements Iterator<E> {
private E[] food;
private int position;
public DinerMenuIterator(E[] food) {
[Link] = food;
}
@Override
public boolean hasNext() {
if(position < [Link] && [Link][position]!=null){
return true;
} else {
return false;
}
}
@Override
public E next() {
return food[position++];
}
@Override
public void remove() {
// ToBeImplemented
}
}74 (c) Paul Fodor & O'Reilly Media
public class Waitress {
Menu pancakeHouseMenu;
Menu dinerMenu;
public Waitress(Menu pancakeHouseMenu, Menu dinerMenu) {
[Link] = pancakeHouseMenu;
[Link] = dinerMenu;
}
public void printMenu() {
Iterator pancakeIterator = [Link]();
Iterator dinerIterator = [Link]();
[Link]("MENU\n----\nBREAKFAST");
printMenu(pancakeIterator);
[Link]("\nLUNCH");
printMenu(dinerIterator);
}
private void printMenu(Iterator iterator) {
while ([Link]()) {
MenuItem menuItem = (MenuItem)[Link]();
[Link]([Link]() + ", ");
[Link]([Link]() + " -- ");
[Link]([Link]());
}
75 }
(c) Paul Fodor & O'Reilly Media
public static void main(String args[]) {
PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
DinerMenu dinerMenu = new DinerMenu();
Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu)
[Link]();
}
}

76
(c) Paul Fodor & O'Reilly Media
class MenuItem {
String name;
String description;
boolean vegetarian;
double price;
public MenuItem(String name, String description,
boolean vegetarian, double price) {
[Link] = name;
[Link] = description;
[Link] = vegetarian;
[Link] = price;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public double getPrice() {
return price;
}
public boolean isVegetarian() {
return vegetarian;
77}
(c) Paul Fodor & O'Reilly Media
}
Common Design Patterns
Creational Structural Behavioral
• Factory • Decorator • Strategy
• Singleton • Adapter • Template
• Builder • Facade • Observer
• Prototype • Flyweight • Command
• Bridge • Iterator
• State

78
Textbook: Head First Design Patterns
(c) Paul Fodor & O'Reilly Media
The State Pattern
 It is used to encapsulate varying behavior for the
same routine based on an object's state object.
 If we model the state machine with constants, it is
difficult to change it later.
 E.g., modify a gumball machine:

79
(c) Paul Fodor & O'Reilly Media
// [Link]

interface GumballMachineState{
void insertQuarter();
void ejectQuarter();
void turnCrank();
void dispense();
void refill(int balls);
}

80
(c) Paul Fodor & O'Reilly Media
class HasQuarterState implements GumballMachineState {
private GumballMachine machine;
public HasQuarterState(GumballMachine machine) {
[Link] = machine;
}
@Override
public void insertQuarter() {
[Link]("You already inserted a quarter");
}
@Override
public void ejectQuarter() {
[Link]("Quarter ejected");
[Link]([Link]());
}
@Override
public void turnCrank() {
[Link]("You turned crank!");
[Link]([Link]());
[Link]();
}
@Override
public void dispense() {
[Link]("You have to turn the crank first!");
}
@Override
public void refill(int balls) {
[Link]("Can only refill if sold out.");
81 } (c) Paul Fodor & O'Reilly Media
}
class SoldState implements GumballMachineState {
private GumballMachine machine;
public SoldState(GumballMachine machine) {
[Link] = machine;
}
@Override
public void insertQuarter() {
[Link]("Wait a second ... you are getting a gumball.");
}
@Override
public void ejectQuarter() {
[Link]("Sorry, you already turned the crank.");
}
@Override
public void turnCrank() {
[Link]("You alread turned the crank. ");
}
@Override
public void dispense() {
[Link]();
if([Link]() > 0) {
[Link]([Link]());
} else {
[Link]("Oops ... out of gumballs");
[Link]([Link]());
}
}
@Override
public void refill(int balls) {
[Link]("Can only refill if sold out.");
82 } (c) Paul Fodor & O'Reilly Media
}
class SoldOutState implements GumballMachineState {
private GumballMachine machine;
public SoldOutState(GumballMachine machine) {
[Link] = machine;
}
@Override
public void insertQuarter() {
[Link]("Machine sold out. You cannot insert a quarter");
}
@Override
public void ejectQuarter() {
}
@Override
public void turnCrank() {
}
@Override
public void dispense() {
}
@Override
public void refill(int balls) {
[Link](balls);
[Link]([Link]());
}
}

83
(c) Paul Fodor & O'Reilly Media
class NoQuarterState implements GumballMachineState {
private GumballMachine machine;
public NoQuarterState(GumballMachine machine) {
[Link] = machine;
}
@Override
public void insertQuarter() {
[Link]("You inserted a quarter");
[Link]([Link]());
}
@Override
public void ejectQuarter() {
[Link]("You haven't inserted a quarter!");
}
@Override
public void turnCrank() {
[Link]("Please insert quarter first!");
}
@Override
public void dispense() {
}
@Override
public void refill(int balls) {
[Link]("Can only refill if sold out.");
}
84 }
(c) Paul Fodor & O'Reilly Media
public class GumballMachine {
private GumballMachineState hasQuarterState;
private GumballMachineState noQuarterState;
private GumballMachineState soldOutState;
private GumballMachineState soldState;
private GumballMachineState state;
private int count = 0;
public GumballMachine(int initialGumballs) {
hasQuarterState = new HasQuarterState(this);
noQuarterState = new NoQuarterState(this);
soldOutState = new SoldOutState(this);
soldState = new SoldState(this);
if(initialGumballs > 0) {
[Link] = initialGumballs;
[Link] = noQuarterState;
}
}
public void setState(GumballMachineState state) {
[Link] = state;
}
public GumballMachineState getHasQuarterState() {
return hasQuarterState;
}
public GumballMachineState getNoQuarterState() {
return noQuarterState;
85 }
(c) Paul Fodor & O'Reilly Media
public GumballMachineState getSoldOutState() {
return soldOutState;
}
public GumballMachineState getSoldState() {
return soldState;
}
public GumballMachineState getState() {
return state;
}
public int getCount() {
return count;
}
public void insertQuarter() {
[Link]();
}

public void setCount(int count) {


if(count >= 0) {
[Link] = count;
}
}
public void ejectQuarter() {
[Link]();
}

86
(c) Paul Fodor & O'Reilly Media
public void turnCrank() {
[Link]();
[Link]();
}
public void dispense() {
[Link]();
}
public void releaseBall() {
if([Link] > 0) {
[Link]("A gumball comes rolling down the slot!");
[Link] --;
}
}
public void refill(int balls) {
[Link](balls);
}

87
(c) Paul Fodor & O'Reilly Media
public static void main(String[] args) {
GumballMachine machine = new GumballMachine(3);
[Link]();
[Link]();

[Link]();
[Link]();
[Link]();
[Link]();

[Link]();
[Link]();

[Link]();
[Link](2);
[Link]();
[Link]([Link]());
[Link]();
[Link]([Link]());
}
88 } (c) Paul Fodor & O'Reilly Media
 You inserted a quarter
 You turned crank!
 A gumball comes rolling down the slot!
 Please insert quarter first!
 You inserted a quarter
 You have to turn the crank first!
 You turned crank!
 A gumball comes rolling down the slot!
 You inserted a quarter
 You turned crank!
 A gumball comes rolling down the slot!
 Oops ... out of gumballs
 Machine sold out. You cannot insert a quarter
 You inserted a quarter
 2
 You turned crank!
 A gumball comes rolling down the slot!
 1
89
(c) Paul Fodor & O'Reilly Media
interface TrafficLightState { // [Link]
void switchOrange();
void switchRed();
void switchGreen();
}

class GreenState implements TrafficLightState {


private TrafficLight light;
public GreenState(TrafficLight light) {
[Link] = light;
}
@Override
public void switchGreen() {
[Link]("Light is already green!");
}
@Override
public void switchOrange() {
[Link]([Link]());
[Link]("Light switched to orange!");
}
@Override
public void switchRed() {
[Link]("First switch the light to orange");
}
90 }
(c) Paul Fodor & O'Reilly Media
class OrangeState implements TrafficLightState {
private TrafficLight light;
public OrangeState(TrafficLight light) {
[Link] = light;
}
@Override
public void switchGreen() {
[Link]("The light has to become red first!");
}
@Override
public void switchOrange() {
[Link]("Light is already orange!");
}
@Override
public void switchRed() {
[Link]("Light switched to red.");
[Link]([Link]());
}
}

91
(c) Paul Fodor & O'Reilly Media
class RedState implements TrafficLightState {
private TrafficLight light;
public RedState(TrafficLight light) {
[Link] = light;
}
@Override
public void switchGreen() {
[Link]("Light switched to green");
[Link]([Link]());
}
@Override
public void switchOrange() {
[Link]("First switch the light to green");
}
@Override
public void switchRed() {
[Link]("Light is already red.");
}
}

92
(c) Paul Fodor & O'Reilly Media
public class TrafficLight {
private TrafficLightState redState;
private TrafficLightState orangeState;
private TrafficLightState greenState;
private TrafficLightState state;
public TrafficLight() {
redState = new RedState(this);
orangeState = new OrangeState(this);
greenState = new GreenState(this);
state = [Link]();
}
public void switchGreen() {
[Link]();
}
public void switchOrange() {
[Link]();
}
public void switchRed() {
[Link]();
}
public TrafficLightState getRedState() {
return redState;
}

93
(c) Paul Fodor & O'Reilly Media
public TrafficLightState getOrangeState() {
return orangeState;
}
public TrafficLightState getGreenState() {
return greenState;
}
public void setState(TrafficLightState state) {
[Link] = state;
}
public static void main(String[] args) {
TrafficLight light = new TrafficLight();
[Link]();
[Link]();
[Link]();
[Link]();
[Link]();
[Link]();
}
}
 First switch the light to green
 Light switched to green
 First switch the light to orange
 Light switched to orange!
 Light is already orange!
94
(c) Paul Fodor & O'Reilly Media
 Light switched to red.
Design Patterns
 Many other design patterns:
 Concurrency patterns:
 Monitor object: An object whose methods are subject to mutual exclusion, thus
preventing multiple objects from erroneously trying to use it at the same time.
 Reactor: A reactor object provides an asynchronous interface to resources that must be
handled synchronously.
 Read-write lock: Allows concurrent read access to an object, but requires exclusive
access for write operations.
 Scheduler: Explicitly control when threads may execute single-threaded code.
Other: Active object, Balking, Event-based asynchronous, Guarded suspension, Join,
Lock, Monitor, Proactor, Read write lock, Thread Pool, Thread-local storage
 Architectural patterns: n-tier, Specification, Publish-subscribe, Service, Locator…
 Use the design patterns, BUT inappropriate use of patterns may unnecessarily
increased complexity.
 Other languages have other patterns.
95
(c) Paul Fodor & O'Reilly Media
Conclusion
Conclusion for this course
 That is all!
 I hope that this course has sparked a lot of
ideas and encourages you to exercise
programming
Thank you!

96
(c) Paul Fodor & O'Reilly Media

You might also like