Bird
Raised Fist0
LLDsystem_design~7 mins

Notification on state change in LLD - System Design Guide

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Problem Statement
When a system's internal state changes, failing to notify interested parts leads to stale data, inconsistent behavior, and poor user experience. Without a clear mechanism to broadcast these changes, components remain unaware and cannot react promptly.
Solution
This pattern uses a mechanism where components interested in state changes register themselves as observers. When the state changes, the system automatically notifies all registered observers, allowing them to update or react accordingly without tight coupling.
Architecture
Subject
Observer 1
Observer 2
Notify all registered observers

This diagram shows a Subject holding state and multiple Observers registered to it. When the Subject's state changes, it notifies all Observers.

Trade-offs
✓ Pros
Decouples state management from components reacting to changes.
Allows multiple observers to react independently to the same state change.
Simplifies adding or removing observers without changing the subject.
✗ Cons
Can lead to performance issues if many observers are notified frequently.
Risk of observers causing side effects or cascading updates if not managed carefully.
Debugging can be harder due to indirect communication between components.
Use when multiple components need to react to changes in shared state, especially in UI frameworks or event-driven systems with moderate to high complexity.
Avoid when the system has very few components or when state changes are rare and simple direct calls suffice.
Real World Examples
Netflix
Uses observer-like patterns in their UI to update video player controls and recommendations when playback state changes.
Uber
Notifies different parts of the app when ride status changes, such as driver arrival or trip completion.
LinkedIn
Updates user feeds and notifications in real-time when new posts or messages arrive.
Code Example
The before code shows a state holder that changes state without notifying anyone. The after code implements the observer pattern where observers register to the subject and get notified automatically when the state changes.
LLD
### Before: No notification on state change
class StateHolder:
    def __init__(self):
        self._state = None

    def set_state(self, value):
        self._state = value


class Observer:
    def update(self, value):
        print(f"Observer received new state: {value}")


state_holder = StateHolder()
observer = Observer()

state_holder.set_state(10)  # Observer is not notified


### After: Observer pattern implemented
class Subject:
    def __init__(self):
        self._state = None
        self._observers = []

    def register(self, observer):
        self._observers.append(observer)

    def unregister(self, observer):
        self._observers.remove(observer)

    def notify(self):
        for observer in self._observers:
            observer.update(self._state)

    def set_state(self, value):
        self._state = value
        self.notify()


class Observer:
    def update(self, value):
        print(f"Observer received new state: {value}")


subject = Subject()
observer = Observer()
subject.register(observer)
subject.set_state(10)  # Observer is notified and prints the new state
OutputSuccess
Alternatives
Polling
Components repeatedly check the state at intervals instead of being notified.
Use when: Use when state changes are infrequent or when push notifications are not feasible.
Callback Functions
Directly pass functions to be called on state change instead of a formal observer registration.
Use when: Use in simple cases with few observers and straightforward state changes.
Summary
Notification on state change prevents components from missing important updates by informing them automatically.
It decouples the state holder from the components that react, improving modularity and flexibility.
This pattern is widely used in UI frameworks and event-driven systems to keep components synchronized.

Practice

(1/5)
1. What is the main purpose of a notification system on state change in software design?
easy
A. To inform interested components immediately when data changes
B. To store data permanently in a database
C. To increase the size of the application
D. To delay updates until the user refreshes manually

Solution

  1. Step 1: Understand the role of notifications

    Notifications alert parts of a system or users when something important changes.
  2. Step 2: Identify the purpose of state change notifications

    They ensure components get updates immediately without waiting or manual refresh.
  3. Final Answer:

    To inform interested components immediately when data changes -> Option A
  4. Quick Check:

    Notification = Immediate update [OK]
Hint: Notifications alert on change, not store or delay [OK]
Common Mistakes:
  • Confusing notification with data storage
  • Thinking notifications delay updates
  • Assuming notifications increase app size
2. Which of the following is the correct method name to notify observers in a typical observer pattern implementation?
easy
A. unsubscribe()
B. updateState()
C. subscribe()
D. notifyObservers()

Solution

  1. Step 1: Recall observer pattern methods

    Common methods include subscribe, unsubscribe, and notifyObservers.
  2. Step 2: Identify the method that sends updates

    notifyObservers() is used to alert all subscribed observers about changes.
  3. Final Answer:

    notifyObservers() -> Option D
  4. Quick Check:

    Notify method = notifyObservers() [OK]
Hint: Notify method usually named notifyObservers() [OK]
Common Mistakes:
  • Confusing subscribe with notify
  • Using updateState() which changes state, not notify
  • Mixing unsubscribe with notification
3. Consider this simplified code snippet for a notification system:
class Subject:
    def __init__(self):
        self.observers = []
    def subscribe(self, observer):
        self.observers.append(observer)
    def notify(self, message):
        for obs in self.observers:
            obs.update(message)

class Observer:
    def update(self, message):
        print(f"Received: {message}")

subject = Subject()
obs1 = Observer()
subject.subscribe(obs1)
subject.notify("State changed")
What will be the output when subject.notify("State changed") is called?
medium
A. Error: update method missing
B. No output
C. Received: State changed
D. Received: None

Solution

  1. Step 1: Trace subscription and notification

    Observer obs1 is subscribed to subject, so it is in the observers list.
  2. Step 2: Check notify method behavior

    notify calls update on each observer with the message "State changed".
  3. Final Answer:

    Received: State changed -> Option C
  4. Quick Check:

    Observer prints message on notify [OK]
Hint: Subscribed observers receive and print messages [OK]
Common Mistakes:
  • Assuming notify does nothing without explicit call
  • Thinking update method is missing
  • Expecting no output if observers list is empty
4. In the following code, what is the main issue that prevents observers from receiving notifications?
class Subject:
    def __init__(self):
        self.observers = set()
    def subscribe(self, observer):
        self.observers.add(observer)
    def notify(self, message):
        for obs in self.observers:
            obs.receive(message)

class Observer:
    def update(self, message):
        print(f"Got: {message}")

subject = Subject()
obs1 = Observer()
subject.subscribe(obs1)
subject.notify("Update")
medium
A. Observers are stored in a set instead of a list
B. Method notify calls obs.receive but Observer has update method
C. subscribe method uses add instead of append
D. Observer class is missing

Solution

  1. Step 1: Check method called in notify

    notify() calls obs.receive(message).
  2. Step 2: Check Observer class methods

    Observer defines update(message), but no receive() method.
  3. Final Answer:

    Method notify calls obs.receive but Observer has update method -> Option B
  4. Quick Check:

    Method name mismatch causes AttributeError [OK]
Hint: Check method names called vs defined in observers [OK]
Common Mistakes:
  • Confusing set vs list for storing observers
  • Ignoring method name mismatches
  • Assuming missing class when it exists
5. You are designing a scalable notification system for state changes in a distributed application. Which design choice best supports efficient notifications to thousands of subscribers without blocking the main process?
hard
A. Use asynchronous message queues to dispatch notifications
B. Notify all subscribers synchronously in a loop
C. Store notifications in a database and poll subscribers
D. Send notifications only when the system restarts

Solution

  1. Step 1: Understand scalability needs

    Thousands of subscribers require non-blocking, efficient notification delivery.
  2. Step 2: Evaluate design options

    Synchronous loops block main process; polling adds delay; restart notifications are impractical.
  3. Step 3: Identify best practice

    Asynchronous message queues decouple notification sending, allowing scalable, fast delivery.
  4. Final Answer:

    Use asynchronous message queues to dispatch notifications -> Option A
  5. Quick Check:

    Async queues = scalable notifications [OK]
Hint: Async queues handle many subscribers efficiently [OK]
Common Mistakes:
  • Using synchronous loops causing delays
  • Relying on polling which is slow
  • Sending notifications only on restart