Session 16 Observer and Iterator Patterns
Session 16 Observer and Iterator Patterns
Design
CS 16 Observer and Iterator
Patterns
Prof. Akanksha Bharadwaj
Observer Pattern
• The Observer Pattern is a behavioral design pattern that establishes a
one-to-many dependency between objects.
• When the subject (observable) undergoes a state change, it automatically
notifies all of its observers (listeners or subscribers).
• This pattern is widely used in event-driven systems and implementations
like the publish-subscribe model.
Key Components of the Observer Pattern
• Subject (Observable): Maintains a list of observers and notifies them of
state changes.
• Observer: Defines an interface for receiving updates from the subject.
• Concrete Subject: Implements the Subject interface, maintaining state
and notifying observers.
• Concrete Observer: Implements the Observer interface and updates itself
when notified.
Java Example: Weather Monitoring System
• Step 1: Define the Observer Interface
import java.util.*;
interface Observer {
void update(float temperature);
}
• Step 2: Define the Subject Interface
interface Subject {
void addObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
• Step 3: Implement Concrete observers.remove(observer);
Subject (WeatherStation) }
@Override
class WeatherStation implements Subject {
public void notifyObservers() {
private List<Observer> observers;
for (Observer observer : observers) {
private float temperature;
observer.update(temperature);
public WeatherStation() {
}
this.observers = new ArrayList<>();
}
}
public void setTemperature(float temperature) {
@Override
this.temperature = temperature;
public void addObserver(Observer observer) {
notifyObservers(); // Notify all observers when
observers.add(observer);
temperature changes
}
}
@Override
}
public void removeObserver(Observer observer) {
• Step 4: Implement Concrete class DesktopDisplay implements Observer {
Observers @Override
public void update(float temperature) {
class MobileDisplay implements Observer {
System.out.println("Desktop Display: Updated
private String name;
temperature -> " + temperature + "°C");
public MobileDisplay(String name) {
}
this.name = name;
}
}
@Override
public void update(float temperature) {
System.out.println(name + " Display: Updated
temperature -> " + temperature + "°C");
}
}
• Step 5: Test the Observer Pattern weatherStation.setTemperature(25.5f);
System.out.println("\nSetting temperature to
public class ObserverPatternDemo {
30°C...");
public static void main(String[] args) {
weatherStation.setTemperature(30.0f);
WeatherStation weatherStation = new
weatherStation.removeObserver(mobileDisplay);
WeatherStation();
System.out.println("\nSetting temperature to
28°C...");
Observer mobileDisplay = new
weatherStation.setTemperature(28.0f);
MobileDisplay("Mobile");
}
Observer desktopDisplay = new DesktopDisplay();
}
weatherStation.addObserver(mobileDisplay);
weatherStation.addObserver(desktopDisplay);
System.out.println("Setting temperature to
25.5°C...");
Iterator Pattern
• The Iterator Pattern is a behavioral design pattern that provides a way
to access elements of a collection sequentially without exposing its
underlying representation.
• This pattern allows traversal of a collection (e.g., lists, sets, or trees) while
keeping the internal implementation hidden.
Key Components of the Iterator Pattern
• Iterator (Interface) → Defines methods for accessing and traversing
elements.
• Concrete Iterator → Implements the Iterator interface and keeps track of
the current position.
• Aggregate (Collection Interface) → Defines a method to create an iterator.
• Concrete Aggregate (Concrete Collection) → Implements the collection
interface and provides an iterator for traversal.
Java Example: Custom Collection with Iterator
• Step 1: Define the Iterator Interface
interface Iterator {
boolean hasNext(); // Check if there is another element
Object next(); // Retrieve the next element
}
• Step 2: Define the Aggregate Interface
interface IterableCollection {
Iterator createIterator();
}
• Step 3: Implement Concrete Iterator @Override
Aggregate (BookCollection)
public String getBookAt(int index) {
class BookCollection implements IterableCollection {
return books[index];
private String[] books;
}
private int size = 0;
public int getSize() {
public BookCollection(int capacity) {
return size;
books = new String[capacity];
}
}
@Override
public void addBook(String book) {
public Iterator createIterator() {
if (size < books.length) {
return new BookIterator(this);
books[size++] = book;
}
}
}
• Step 5: Test the Iterator Pattern
public class IteratorPatternDemo {
public static void main(String[] args) {
BookCollection bookCollection = new BookCollection(5);
bookCollection.addBook("Design Patterns");
bookCollection.addBook("Clean Code");
bookCollection.addBook("Refactoring");
bookCollection.addBook("Effective Java");
Iterator iterator = bookCollection.createIterator();
System.out.println("Books in collection:");
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
Thank You!