[Refactoring Guru | Observer](https://refactoring.guru/design-patterns/observer) > **Observer** is a behavioral design pattern that lets you define a subscription mechanism to notify multiple objects about any events that happen to the object they’re observing. Observer is used everywhere, especially in reactive environment like web UI. - Consumers of Message Queue (Kafka) - When a consumer subscribe to a topic, it observes the topic updates - [RxJS | Reactive Extensions Library for JavaScript](https://rxjs.dev/) - `document.addEventListener()` - Frontend reactive stores - [Svelte Store](https://svelte.dev/docs/svelte/svelte-store) - [Vue Pinia Store](https://pinia.vuejs.org/) ## Examples ### Vue Let's use [[Vue]]'s reactivity design as an example. Read the docs for [`ref()`](https://vuejs.org/api/reactivity-core.html#ref) and [`reactive()`](https://vuejs.org/api/reactivity-core.html#reactive) `reactive()` returns a reactive proxy of the object. So [[Kunkun/Design Patterns/Proxy|Proxy]] pattern can be used to implement #observer-design-pattern. Vue’s reactivity system, including `ref()`, is based on the **Observer pattern** combined with **Proxies and dependency tracking**. #### How Vue Uses the Observer Pattern: 1. **Reactive State (`ref`, `reactive`)**: - When a reactive value is accessed (`ref.value` or `reactiveObject.prop`), Vue tracks which components or effects depend on it. 2. **Effect Tracking (Dependency Collection)**: - When a reactive value changes, Vue notifies all dependent components/effects to re-run. 3. **Reactivity System**: - Vue maintains a **global effect stack**, so when a reactive value is read during execution, Vue knows which effect depends on it. #### Sample Code ```ts class Dep { constructor() { this.subscribers = new Set(); } depend() { if (activeEffect) { this.subscribers.add(activeEffect); } } notify() { this.subscribers.forEach((sub) => sub()); } } let activeEffect = null; function watchEffect(effect) { activeEffect = effect; effect(); activeEffect = null; } function reactive(obj) { const depMap = new Map(); // Track dependencies for each property return new Proxy(obj, { get(target, key) { if (!depMap.has(key)) { depMap.set(key, new Dep()); } depMap.get(key).depend(); return target[key]; }, set(target, key, value) { target[key] = value; if (depMap.has(key)) { depMap.get(key).notify(); } return true; } }); } // Usage Example const state = reactive({ count: 0 }); watchEffect(() => { console.log(`Count changed: ${state.count}`); }); state.count++; // Triggers reactivity ```