Software design patterns
Acknowledge
• Some of the covered materials are based on SOEN 344 at Concordia, SE463 at UW, SENG321 at UVic, CSE331 at University of Washington and previous EECS3311 offerings:
• Nikolaos Tsantalis, Jo Atlee, Marty Stepp, Mike Godfrey, Jonathan S. Ostroff, M. Ernst, S. Reges, D. Notkin, R. Mercer, Davor Svetinovic, Jack Jiang, Jackie Wang
Outlines
▪ Java Design Patterns (Behavioral Patterns) ▪ Visitor Design Pattern
▪ Iterator Pattern
▪ State Design Pattern
▪ Observer design patterns
Pattern: Visitor
What’s It All About?
• Allows for new operations to be defined and used on elements of an object structure without changing the contents of those elements.
• The Key is Double Dispatch • choosing the method to invoke based both on receiver
and argument types
Where Applicable
• Rarely Changing Object Structures
• Using Unrelated Operations
• Many Classes with Differing Interfaces
Visitor design pattern
• Add an accept(Visitor) method to the "element" hierarchy
• Create a "visitor" base class w/ a visit() method for every "element" type
• Create a "visitor" derived class for each "operation" to do on "elements"
• Client creates "visitor" objects and passes each to accept() calls
How it Works
• Concrete Object Structure
• Assume Rarely Changing
• Bank Accounts
Add an Inquiry Operation
• Check balances and display account summary
• Don’t Want to Change Structure
• Create a Visitor Structure
• Account Visitor
Account Visitor Interface
Inquiry Visitor
Account Structure Change
Account Interface
Checking Account
Savings Account
Main Method
Pattern: Iterator
What’s It All About?
• Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
• Separate traversal code from the data collection itself.
Java Collections
Figure source: https://techvidvan.com/tutorials/wp-content/uploads/sites/2/2020/03/collection-framework-hierarchy-in-java.jpg
Basic Structure
• Iterator keeps a Cursor to current location in a collection.
• Most collections store their elements in simple lists. However, some of them are based on stacks, trees, graphs and other complex data structures.
• But no matter how a collection is structured, it must provide some way of accessing its elements so that other code can use these elements. There should be a way to go through each element of the collection without accessing the same elements over and over.
Visualizing iterator pattern at runtime
ArrayList
ArrayList
Person
Iterator
isDonefirst
Iterator for A Binary Tree
Pattern: State Model
Motivating Problem Consider the reservation panel of an online booking system:
Motivating Problem
State Transition Diagram
State Pattern
• State Design Pattern allows an object to change its behavior when the internal state of that object changes.
• The state design pattern is generally used in cases where an object depends on its state and its behavior must be changed during run time depending on its internal state.
• A typical behavioral design pattern;
• Context: Defines an interface to client to interact. It maintains references to concrete state object which may be used to define current state of object.
• State: Defines interface for declaring what each concrete state should do.
• ConcreteState: Provides implementation for methods defined in State.
State Pattern Diagram
A Simple Example
In this example we will model a mobile state scenario. With respect to alerts, a mobile can be in different states. For example, vibration and silent. Based on this alert state, behavior of the mobile changes when an alert is to be done.
Source: https://www.geeksforgeeks.org/state-design-pattern/
The key classes
• The State Interface
interface MobileAlertState {
public void alert(AlertStateContext ctx); }
The key classes
• Context class AlertStateContext {
private MobileAlertState currentState;
public AlertStateContext() {
currentState = new Vibration(); }
public void setState(MobileAlertState state) {
currentState = state; }
public void alert() {
currentState.alert(this); }
}
The key classes
• States class Vibration implements MobileAlertState {
@Override public void alert(AlertStateContext ctx) {
System.out.println("vibration..."); }
}
class Silent implements MobileAlertState {
@Override public void alert(AlertStateContext ctx) {
System.out.println("silent..."); }
}
The key classes
• Demo class StatePattern {
public static void main(String[] args) {
AlertStateContext stateContext = new AlertStateContext(); stateContext.alert(); stateContext.alert(); stateContext.setState(new Silent()); stateContext.alert(); stateContext.alert(); stateContext.alert();
} }
Output:
vibration... vibration... silent... silent... silent...
Pattern: Observer
Observer Pattern
• Defines a “one-to-many” dependency between objects so that when one object changes state, all its dependents are notified and updated automatically
• a.k.a Dependence mechanism / publish- subscribe / broadcast / change-update
Subject & Observer
• Subject • the object which will frequently change its state and
upon which other objects depend
• Observer • the object which depends on a subject and updates
according to its subject's state.
Observer Pattern - Example
a b c 60
y x 5030
30 20 10
z 801010 a b c a
b c
a = 50% b = 30% c = 20%
change notification
requests, modifications
Observers
Subject
Observer Pattern - Working A number of Observers “register” to receive notifications of changes to the Subject. Observers are not aware of the presence of each other.
When a certain event or “change” in Subject occurs, all Observers are “notified’.
Observer Pattern - Key Players
• Subject • has a list of observers
• Interfaces for attaching/detaching an observer
• Observer • An updating interface for objects that gets notified of changes in a
subject
• ConcreteSubject • Stores “state of interest” to observers
• Sends notification when state changes
• ConcreteObserver • Implements updating interface
Observer Pattern - UML
Subject
attach (Observer)
detach (Observer)
Notify ()
Observer
Update()
ConcreteObserver
Update()
observerState
ConcreteSubject
SetState()
GetState()
subjectState
observers
subject
For all x in observers{
x.Update(); }
observerState=
subject.getState();
Observer Pattern - Collaborations
:ConcreteSubject :ConcreteObserver-1 :ConcreteObserver-2
GetState()
Notify()
Update()
SetState()
GetState()
Update()
Observer Pattern - Implementation
interface Observer {
void update (Observable sub, Object arg)
// repaint the pi-chart
} Java terminology for Subject.
public void addObserver(Observer o) {}
public void deleteObserver (Observer o) {}
public void notifyObservers(Object arg) {}
class Observable {
…
}
public boolean hasChanged() {}
Observer Pattern - Consequences
• Loosely Coupled • Reuse subjects without reusing their observers, and vice versa
• Add observers without modifying the subject or other observers
• Abstract coupling between subject and observer • Concrete class of none of the observers is known
• Support for broadcast communication • Subject doesn’t need to know its receivers
• Unexpected updates • Can be blind to changes in the system if the subject is changed (i.e.
doesn’t know “what” has changed in the subject)
Exercise
• Design the system for the flight online booking system;
• Draw the class diagram of the online booking system;