This article explores the Observer Pattern as a behavioral design pattern to achieve loose coupling between components in a system. It defines the subject-observer relationship, illustrating how it enables one-to-many communication where changes in a subject automatically notify interested observers without tight dependencies. The pattern helps in designing systems where multiple parts need to react to a single event independently, improving maintainability and extensibility.
Read original on Dev.to #systemdesignIn many applications, especially e-commerce or notification systems, a single event often triggers multiple subsequent actions. A common naive approach is to have the originating service directly call all dependent services. For example, an `OrderService` might directly call `EmailService`, `InventoryService`, and `ShippingService` after an order is placed. This leads to tight coupling, making the system brittle and difficult to extend. Adding a new action requires modifying the `OrderService`, violating the Open/Closed Principle.
The Observer Pattern is a behavioral design pattern that establishes a one-to-many dependency between objects. When a 'subject' (publisher) changes its state or publishes an event, all registered 'observers' (subscribers) are automatically notified. The key benefit is that the subject does not need to know the concrete implementation details of its observers; it only knows how to notify them through a common interface. This significantly reduces direct dependencies.
E-commerce Order Processing Example
When an order is placed, the `OrderService` (subject) notifies all registered `IOrderObserver` implementations. These could include `EmailObserver`, `InventoryObserver`, and `ShippingObserver`. If a new requirement emerges (e.g., SMS notification), a new `SmsObserver` can be created and subscribed without altering the `OrderService`.
While effective for decoupling, the Observer Pattern comes with its own set of considerations for system designers:
Though related, the Observer Pattern and Pub/Sub differ primarily in their architecture. The Observer Pattern often involves direct, in-process communication where the subject maintains explicit references to its observers. Pub/Sub, conversely, introduces an intermediary (an event broker or message bus) that decouples publishers from subscribers. This enables communication across different processes or even distributed services, making Pub/Sub more suitable for large-scale distributed systems, whereas the Observer Pattern is typically used for internal component communication within a single application.