JS and Design Patterns - Chapter 4 🚀
Tags: javascript, webdev, programming, codequality
Published: 2021-01-23 20:40:47

Table Of Contents
        * 🤓[INTRODUCTION](#intro)
        * 👀[ABOUT OBSERVER](#about)
        * 🦄[ENTITIES](#entities)
        * 🌍 [REAL WORLD ANALOGY?](#rw)
        * 📰[NEWS ANALOGY](#news)
        * 📈 [STOCK ANALOGY](#stocks)
        * ❓ [WHEN TO USE?](#when-use)
        * ⚙ [RxJS applicability](#rxjs)
        * ✅[PROS](#pros)
        * ❌[CONS](#cons)
        * 🙏[THANK YOU](#thank-you)

## 🤓 INTRODUCTION <a name="intro"></a>
Hello, codedudes and codedudettes, I hope you are having a great day! Let's make it even better, let's learn something new. Software development is a neverending story where you always learn something new, personally, I always push myself to do the best and to learn as much as I can. But remember, don't overwork yourself! 

Today, we are talking about a very popular design pattern, The Observer Pattern.

![Observer](https://media.giphy.com/media/DQv0TCvjLklB6/giphy.gif)


## 👀 ABOUT OBSERVER <a name="about"></a>
The Observer Pattern 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. In other words, the Observer Pattern defines a one-to-many type of dependence between different objects, and it ensures that the change of the state in one object gets automatically reflected in all dependant objects!


## 🦄 ENTITIES <a name="entities"></a>

Entities that will participate in the Observer paradigm are:
- **SUBJECT**
  It keeps a reference towards its observer. One object can have 
  many Observer objects
  It provides an interface for "attaching" and "detaching" 
  observer objects
- **CONCRETE SUBJECT**
  It keeps the state of interest of the Concrete Observer objects
  It sends notifications to its observers when the state changes
- **OBSERVER**
  It defines an interface for updating the objects after the state 
  of the changes in the objects of the class type Subject 
- **CONCRETE OBSERVER**
  It keeps a reference to the Concrete Subject objects
  It keeps the state that should stay consistent with the state of 
  the parent class
  It implements an interface for updating object that is defined 
  in the Observer class

Let's see the code 👩‍💻 (❗ And as always, read the comments 😊)

![Observer1](https://media.giphy.com/media/3o6Mbj2O2nmj1POLVS/giphy.gif)

```javascript
//The subject class
//It provides an interface
//for "attaching" and "detaching" 
//observer objects
class Subject{
	constructor(){
    	this.observerList = [];
    }
    attach(observer) { 
        console.log(`📎 Attaching observer... ${observer.name}`);
    	this.observerList.push(observer);
    }
    detach(observerId) {
        let observer = this.observerList.find(item => item.id === observerId);
        console.log(`🔗 Detaching observer... ${observer.name}`);
    	this.observerList = this.observerList.filter(item => item.id !== observerId)
    }
	notify() { 
        console.log('🟢The Notification process starts...');
    	for (let i = 0; i < this.observerList.length; i++) {
        	this.observerList[i].update()
        }
        console.log('🔴The Notification process ends...');
    };
}
//It keeps the state of interest of the Concrete Observer objects
//It sends notifications to its observers when the state changes
class ConcreteSubject extends Subject {
	constructor(){
        super();
    }
    //return subject state
    getSubjectState(){ return this.subjectState; }
    //set new subject state
    setSubjectState(subjectState){ this.subjectState = subjectState; }
    function(){
    	return { getSubjectState, setSubjectState }
    }
};
//It defines an interface for updating the objects after the state 
//of the changes in the objects of the class type Subject 
class Observer{
	update() { return; }
};
//The concrete observer class will extend an observer class
//It keeps a reference to the Concrete Subject objects
//It keeps the state that should stay consistent with the state of 
//the parent class
class ConcreteObserver extends Observer{
	constructor(id, subject, name){
        super();
        this.id = id;
    	this.subject = subject; //a reference to the Concrete Subject object
        this.name = name;
        this.observerState = ""; // the state that should stay consistent with the state of
                                 //the parent class
    }
    
    //The interface for update object
  	update() { 
    	this.observerState = this.subject.subjectState; 
        console.log(`${this.name} new state is: ${this.observerState}`);
    }
    
   getSubject() {
    	return this.subject;
    }
    
    setSubject(subject){
    	this.subject = subject;
    }
};
//we will instantiate our concrete subject class that should be observed
var s = new ConcreteSubject();
//attaching the first concrete observer with an id of 1, 
//passing the concrete subject instance
//passing the name of the observer
s.attach(new ConcreteObserver(1, s, 'First observer'));
//attaching the second observer
s.attach(new ConcreteObserver(2, s, 'Second observer'));
//changing the subject state
s.setSubjectState("subject changed");
//notifying OBSERVERS (we have two observer at the moment) that the state was changed
s.notify();
/* OUTPUT OF THE NOTIFY FUNCTION
🟢 The Notification process starts...
First observer new state is: subject changed
Second observer new state is: subject changed
🔴 The Notification process ends...
*/
//detaching the observer with an id of 1
s.detach(1)
//changing the subject state
s.setSubjectState("removed one observer");
//notifying OBSERVER (because we detached our observer with an id of 1
//we are left with only one observer that should get notified about the
//change of the state
s.notify();
/* OUTPUT OF THE NOTIFY FUNCTION
🟢 The notification process starts...
Second observer new state is: removed one observer
🔴 The Notification process ends...
*/
```
Please try executing this code, it is always better to look it in the text editor of your preference, and of course, play with it, try adding one more subject and as many observers as you want.

Here is the UML diagram for the visual learners.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/6tydi8jy8n3rncr8id6v.png)


## 🌎 REAL WORLD ANALOGY<a name="rw"></a>

### 📰 NEWSPAPER / MAGAZINE ANALOGY <a name="news"></a>
If you subscribe to a newspaper or magazine, you no longer need to go to the store to check if the next issue is available. Instead, the publisher sends a new issue directly to your mailbox right after publication or even in advance. The publisher maintains a list of subscribers and knows which magazines they are interested in. Subscribers can leave the list at any time when they wish to stop the publisher from sending new magazine issues to them.

### 📈 STOCK ANALOGY <a name="stocks"></a>
The observer pattern also applies to the real world in terms of the stocks. For example, you can have an investor, a company for example Apple. Apple has stocks, investors invest their 💰 into the Apple stocks, thus, they would certainly like to be notified when the stocks change so they can turn their strategy around.
**In this case, a Stock is a Subject, Apple stock is a Concrete Subject, Investor is an Observer, and let's say Warren Buffet is a Concrete Observer.**

## ❓ WHEN TO USE THE OBSERVER PATTERN?<a name="when-use"></a>
You could use the observer pattern when changes to the state of one object may require changing other objects, and the actual set of objects is unknown beforehand or changes dynamically.

Use the pattern when some objects in your app must observe others, but only for a limited time or in specific cases.

## ⚙ RxJS OBSERVABLE (ANGULAR)<a name="rxjs"></a>

>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 is the pattern that RxJS observable is using.

**Observable** — this is the thing that clients observe, it is sometimes called the subject.

**Observer** — this is a class that wants to be notified when the subject’s state changes in an interesting way.

An Example of creating observables:
```typescript
import { Observable } from 'rxjs';

const observable = new Observable(function subscribe(observer) {
  var id = setInterval(() => {
    observer.next('hi')
  }, 1000);
});
```
An Example of subscribing to an observable
```typescript
observable.subscribe(x => console.log(x));
```
When calling observable.subscribe with an Observer, the function subscribe in Observable.create(function subscribe(observer) {...}) is run for that given Observer. **Each call to observable. Subscribe triggers its own independent setup for that given Observer.**

## ✅ PROS <a name="pros"></a>
- Open/Closed Principle. You can introduce new subscriber classes without having to change the publisher’s code (and vice versa if there’s a publisher interface).
- You can establish relations between objects at runtime.

## ❌ CONS <a name="cons"></a>
- Subscribers are notified in random order.

# 🙏 THANK YOU FOR READING!<a name="thank-you"></a>
Please leave the comment, tell me about you, about your work, comment your thoughts on the filter method, connect with me via  [Twitter](https://twitter.com/lazar_dev) or  [LinkedIn](https://www.linkedin.com/in/lazar-stankovic-44a199177/). 

Let this year be your year, let this year be our year. Until the next typing...

Have a nice time!

References:
School notes...
[medium](https://kevinwkds.medium.com/angular-observable-81eea33a1aab#:~:text=Angular%20uses%20the%20Observer%20pattern,acted%20on%20in%20some%20way.)
[refactoring](https://refactoring.guru/design-patterns/observer)

☕ SUPPORT ME AND KEEP ME FOCUSED!
<a href='https://ko-fi.com/Z8Z33D1HJ' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://cdn.ko-fi.com/cdn/kofi4.png?v=2' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>
😊