Summary
Pattern Name | Observer Pattern |
Pattern Type | Behavioral Pattern |
Scope | Object |
Other Names | Dependents Publish/Subscribe (pub/sub) Publish/Listener |
Tagline | Notify state change to all dependent objects |
Use cases | When we want to implement Publish-Subscribe of state change between objects |
Related Patterns | Mediator Singleton |
Difficulty Level | Medium |
Implementations |
Definition
Observer pattern deals with state change between related objects. When one object depends on any state of another object, then when the state changes the dependent object needs to be notified. Observer pattern enables the dependent objects to subscribe to the state change of the subject-object.
Observer pattern defines one-to-many dependencies between objects. Many observer objects can subscribe to the subject and automatically be notified of the change in subject. When any observer does not have any interest in the subject, they can unsubscribe from that subject.
Use Cases
Here are a few use cases of the Observer pattern-
- When changes in one object, require changes in other objects.
- When we do not know how many objects(subscribers) are impacted by the change in the subject.
- When the subscribing objects need the ability to unsubscribe to the subject change.
Implementation
Observer pattern has 4 elements.
- Subject Interface: Interface for the concrete subject cl.
- Concrete Subject: class to which the observers subscribe.
- Observer Interface: Interface (or abstract class) for the observer classes.
- Concrete Observer: Classes that subscribe to the subject.
Take a look at the implementation diagram.
Follow the steps below to implement Observer pattern:
- Create an interface for the subject class. This interface needs to define functions to set & get the state, attach an observer to the subject, and a way to notify observers about the state change.
- Create a subject class.
- Store a list of observers in the subject class.
- When a subscriber subscribes to the subject, then add the object to the observer list.
- When the state is changed in the subject, then inform all the observers in the list.
- Create an interface for the observer classes.
- Create observer classes and implement the observer interface.
- In the observer constructor, take a subject-object as para. Save the subject in the observer, and call the subject to attach the method to add the observer to the observer list of the subject.
- Implement send update method, which the subject can call to and send the state updates.
- In the client, create a subject-object. create observers and pass the subject to them.
- After that whenever the state changes in the subject(using the setState), the observers will get the update.
Examples
Example #1: General Observer
Let’s take the example of a general observer implementation.
Subject
// Subject Interface
interface Subject
getState(): int
setState(state: int)
attach(observer: Observer)
notifyObservers()
end interface
// Subject Concrete Class
class ConcreteSubject implements Subject
var state: int
// Observer array
var observerList: Observer[]
method getState(): int
return state
end method
method setState(stateParam: int)
state = stateParam
notifyObservers()
end method
method attach(observer: Observer)
observerList.add(observer)
end method
method notifyObservers()
for observer in observerList
observer.sendUpdate()
end for
end method
end class
Observer
// Observer abstract class
abstract class Observer
var subject: Subject
abstract sendUpdate()
end class
// Observer implementation
class ObserverOne extends Observer
constructor(subjectParam: Subject)
subject = subjectParam
subject.attach(this)
end constructor
method sendUpdate()
output "Received in ObserverOne: " + subject.getState()
end method
end class
class ObserverTwo extends Observer
constructor(subjectParam: Subject)
subject = subjectParam
subject.attach(this)
end constructor
method sendUpdate()
output "Received in ObserverTwo: " + subject.getState()
end method
end class
Demo
Subject subject = new ConcreteSubject()
new ObserverOne(subject)
new ObserverTwo(subject)
output "Setting subject value to 10"
subject.setState(10)
output "Setting subject value to 999"
subject.setState(999)
Output
Setting subject value to 10
Received in ObserverOne: 10
Received in ObserverTwo: 10
-----------------------------
Setting subject value to 999
Received in ObserverOne: 999
Received in ObserverTwo: 999
Code Implementations
Use the following links to check Observer pattern implementation in specific programming languages.