- Published on
Learning Design Patterns: Observer Pattern - Always Listening, Always Understanding
- Authors
- Name
- Dan Tech
- @dan_0xff
The Observer Pattern is an important design pattern that offers a solution for receiving and processing changes on a specific data stream by Observing (monitoring) that data stream.
A data stream can have 0, 1, or many objects observing it. And when the data stream changes, all Observers will receive this information to execute the necessary corresponding logic.
The Problem In Software
Suppose you are a Dev for an e-commerce platform. On the platform's Mobile app, there's a feature that allows customers to register early for a Flash Sale Event. And this Flash Sale Event can be registered for by thousands of customers at the same time. When the event occurs, the customer's Mobile device will receive a notification 15 minutes earlier to prepare for shopping.
How can 1000 customers receive the notification at the right time? Create 1000 while(true) loops to check when it's time for the Flash Sale to send a notification? That's crazy!!! You have to use the Observer Pattern!
Solving with the Observer Pattern
With the Observer Pattern, we have 2 concepts: Subscriber and Publisher.
The Flash Sale event acts as the Publisher, and the Customers are the top-notch Subscribers. Each time a customer wants to receive a notification, they simply subscribe to the Flash Sale Event. When the event takes place, the Publisher (Flash Sale Event) will send an Event (Notification) to each customer so that no one misses this one-of-a-kind Flash Sale deal!!!
Sample Code for Observer Pattern
interface Subscriber {
fun receive(data: String)
}
interface Publisher {
fun addSubscriber(s: Subscriber)
fun removeSubscriber(s: Subscriber)
fun publishEvent(data: String)
}
class FlashSale(val name: String) : Publisher {
val subscribers = MutableSet()
override fun addSubscriber(s: Subscriber) {
subscribers.add(s)
}
override fun removeSubscriber(s: Subscriber) {
subscribers.remove(s)
}
override fun publishEvent(data: String) {
subscribers.foreach {
it.receive(data)
}
}
}
class Customer(val name: String) : Subscriber {
fun subscribeToFlashSale(flashSale: FlashSale) {
flashSale.addSubscriber(this)
}
override fun receive(data: String) {
println(data)
}
}
fun main() {
val flashSale = FlashSale("Sale 9-9")
val customer = Customer("Dan Tech")
customer.subscribeToFlashSale(flashSale)
flashSale.publishEvent("Sale Zo zo")
}
When to use the Observer Pattern
When changes to the state of one Object may require changes to other Objects.
For example, in Mobile and Web programming, we often use hooks to observe the state of a Component, which is the Observer Pattern.
Follow my Youtube and Facebook channels to update more knowledge! @dantech