89 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			89 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
---
 | 
						|
tags:
 | 
						|
  - OOP
 | 
						|
  - design-patterns
 | 
						|
---
 | 
						|
 | 
						|
# Observer pattern
 | 
						|
 | 
						|
The Observer design pattern is also known as the 'publish/subscribe' pattern.
 | 
						|
 | 
						|
> The observer pattern is a software design pattern in which an object, called
 | 
						|
> the subject, maintains a list of its dependents, called observers, and
 | 
						|
> notifies them automatically of any state changes, usually by calling one of
 | 
						|
> their methods.
 | 
						|
 | 
						|
The observer pattern instantiates a **one-to-many** relationship between the
 | 
						|
subject and its observers: when one object updates, it notifies many other
 | 
						|
objects that it has been updated.
 | 
						|
 | 
						|
This is another design pattern that is useful when implementing a global state.
 | 
						|
When the subject updates its subjects must follow suit and adapt to its changes.
 | 
						|
Here the subject is the instrument for maintaining the global state.
 | 
						|
 | 
						|
## Subject class
 | 
						|
 | 
						|
This class maintains a list of observers that will be notified when it is
 | 
						|
updated. It should have the following attributes:
 | 
						|
 | 
						|
- array of existing observers
 | 
						|
- an `addObserver` method which pushes an observer onto the observers array
 | 
						|
- a `removeObserver` method that does the opposite
 | 
						|
- a `notify` method that broadcasts to the observers that a change has happened
 | 
						|
 | 
						|
## Observer class
 | 
						|
 | 
						|
Observers must implement an `update` method that will be called by the subject's
 | 
						|
`notify` method.
 | 
						|
 | 
						|
## Example
 | 
						|
 | 
						|
```js
 | 
						|
class Subject {
 | 
						|
  observers = [];
 | 
						|
 | 
						|
  getCurrentTime() {
 | 
						|
    var d = new Date();
 | 
						|
    return `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}`;
 | 
						|
  }
 | 
						|
 | 
						|
  addObserver(...observer) {
 | 
						|
    for (const o of observer) {
 | 
						|
      this.observers.push(o);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  removeObserver(observer) {
 | 
						|
    const match = this.observers.findIndex((element) => element === observer);
 | 
						|
    this.observers.splice(match, 1);
 | 
						|
  }
 | 
						|
  notify() {
 | 
						|
    for (const o of this.observers) {
 | 
						|
      o.update(`I was updated at ${this.getCurrentTime()}`);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
class ObserverA {
 | 
						|
  state = "I am observer A";
 | 
						|
  update(newState) {
 | 
						|
    this.state = newState;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
class ObserverB {
 | 
						|
  state = "I am observer B";
 | 
						|
 | 
						|
  update(newState) {
 | 
						|
    this.state = newState;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
let subjectInstance = new Subject();
 | 
						|
let obsAInstance = new ObserverA();
 | 
						|
let obsBInstance = new ObserverB();
 | 
						|
 | 
						|
subjectInstance.addObserver(obsAInstance, obsBInstance);
 | 
						|
 | 
						|
subjectInstance.notify();
 | 
						|
console.log(obsBInstance.state);
 | 
						|
```
 |