Yongjae Kim 2024. 12. 8. 09:57

 

With the observer pattern,

we can subscribe certain objects, the observers, to another object, called the observable.

 

Whenever an event occurs, the observable notifies all its observers!

 

  • observers: an array of observers that will get notified whenever a specific event occurs

An observable object usually contains 3 important parts:

 

  • subscribe(): a method in order to add observers to the observers list
  • unsubscribe(): a method in order to remove observers from the observers list
  • notify(): a method to notify all observers whenever a specific event occurs

 

Code Example

// observable.js

class Observable {
  constructor() {
    this.observers = [];
  }

  subscribe(f) {
    this.observers.push(f);
  }

  unsubscribe(f) {
    this.observers = this.observers.filter(subscriber => subscriber !== f);
  }

  notify(data) {
    // function 들이 Data 를 이용하여 실행된다.
    this.observers.forEach(observer => observer(data)); 
  }
}

export default new Observable();

 

// App.js

import React from "react";
import { Button, Switch, FormControlLabel } from "@material-ui/core";
import { ToastContainer, toast } from "react-toastify";
import observable from "./Observable";

function handleClick() {
  observable.notify("User clicked button!"); // 값은 data
}

function handleToggle() {
  observable.notify("User toggled switch!"); // 값은 data
}

function logger(data) {
  console.log(`${Date.now()} ${data}`);
}

function toastify(data) {
  toast(data, {
    position: toast.POSITION.BOTTOM_RIGHT,
    closeButton: false,
    autoClose: 2000
  });
}

observable.subscribe(logger); // logger 함수를 구독에 추가
observable.subscribe(toastify); // toastify 함수를 구독에 추가

export default function App() {
  return (
    <div className="App">
      <Button variant="contained" onClick={handleClick}>
        Click me!
      </Button>
      <FormControlLabel
        control={<Switch name="" onChange={handleToggle} />}
        label="Toggle me!"
      />
      <ToastContainer />
    </div>
  );
}

Pros

  • Using the observer pattern is a great way to enforce separation of concerns and the single-responsiblity principle.
  • The observer objects aren’t tightly coupled to the observable object, and can be (de)coupled at any time.
  • The observable object is responsible for monitoring the events, while the observers simply handle the received data.

Cons

If an observer becomes too complex, it may cause performance issues when notifying all subscribers.