Skip to main content

🧩 Observer Pattern

βœ… Intent​

  • Allow an object to emit events without knowing who will react to them
  • Enable easy modification and extension by simply adding new listeners

βœ… Motivation​

  • Notification targets can be added or replaced dynamically
  • Separate each concern into its own class, improving testability and reusability

βœ… When to Use​

  • When you want to decouple event emission from its handling logic
  • When the number of notification handlers may increase over time

βœ… Code Example​

// Observer むンターフェース
interface Observer {
update(email: string): void;
}

// ConcreteObserver
class Mailer implements Observer {
update(email: string): void {
console.log(`ι€δΏ‘γ—γΎγ—γŸ: ${email} β†’ γ‚ˆγ†γ“γοΌ`);
}
}

// SubjectοΌˆι€šηŸ₯ε…ƒοΌ‰
class UserService {
private observers: Observer[] = [];

addObserver(observer: Observer): void {
this.observers.push(observer);
}

notifyObservers(email: string): void {
this.observers.forEach((observer) => observer.update(email));
}

registerUser(email: string): void {
console.log(`γƒ¦γƒΌγ‚ΆγƒΌη™»ιŒ²: ${email}`);
this.notifyObservers(email);
}
}

// εˆ©η”¨δΎ‹
const service = new UserService();
service.addObserver(new Mailer());
service.registerUser("user@example.com");

βœ… Explanation​

This code applies the Observer pattern to design a system where UserService (the subject)
notifies multiple Observer instances (subscribers) of an event.
The Observer pattern defines a one-to-many dependency between objects so that
when one object changes state, all its dependents are notified automatically.

1. Overview of the Observer Pattern​

  • Subject: Maintains a list of observers and notifies them of events

    • Represented by UserService in this code
  • Observer: Interface for all objects that want to receive notifications

    • Represented by Observer
  • ConcreteObserver: Implements the Observer interface and defines custom handling logic

    • Represented by Mailer

2. Key Classes and Their Roles​

  • Observer

    • Common interface for subscribers
    • Declares the method update(email: string): void
  • Mailer

    • A concrete observer that implements Observer
    • Implements update to send an email notification
  • UserService

    • The subject that emits notifications
    • Has addObserver to register observers
    • Uses notifyObservers to notify all registered observers
    • Executes registerUser, which triggers the notification process

3. UML Class Diagram​

4. Benefits of the Observer Pattern​

  • Loose Coupling: Subjects and observers are loosely coupled; adding/removing observers does not impact the subject
  • Extensibility: New observers can be added by simply implementing the Observer interface
  • Real-Time Notifications: Allows real-time propagation of state changes

This design is highly effective in event-driven architectures,
especially when multiple objects need to be notified of a single change in state.
It enhances both maintainability and scalability of the codebase.