[디자인 패턴] 관찰자 패턴_Observer pattern (JavaScript)

2024. 11. 17. 21:30Web_Programming

관찰자 패턴이란?

관찰자 패턴(Observer Pattern) 은 이벤트가 발생할 때 옵저버블(Observable)을 사용해 구독자(Subscriptor)에게 알리는 방법입니다.

예시 코드

  • Observable(Publisher) - 구독자에게 알림을 보내는 "관찰 가능한" 객체입니다.
const observers = new Set();

const Observable = {
  notify(data) {
    observers.forEach(observer => observer(data))
  },
  subscribe(observer) {
    observers.add(observer);
  },
  unsubscribe(observer) {
    observers.delete(observer);
  }
};

export default Object.freeze(Observable);
  • Subscriptor (Observer) - 관찰 가능한 객체를 "구독"하고 알림을 받을 수 있습니다. 
import Observable from './Observable';

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

Observable.subscribe(logger);
import Observable from './Observable';

const demoButton = document.querySelector('#demo .Button');

demoButton.addEventListener('click', () => {
  Observable.notify('클릭');
});

 

 

 

참고 라이브러리 코드

  • Zustand에서 제공하는 subscribe 기능도 관찰자 패턴의 응용 사례입니다. 상태가 변경되었을 때 특정 로직을 실행하도록 구성합니다.
const subscribeWithSelector = (listener, selector, equalityFn = Object.is) => {
  // 구독 시 이 변수의 클로저가 생성된다.
  let currentSlice = selector(state);

  // 상태가 변경될 때마다 실행해 줄 함수
  function listenerToAdd() {
    const nextSlice = selector(state);
    if (!equalityFn(currentSlice, nextSlice)) {
      const previousSlice = currentSlice;
      listener((currentSlice = nextSlice), previousSlice);
    }
  }

  listeners.add(listenerToAdd);
  return () => listeners.delete(listenerToAdd);
};

장단점

장점

  1. 관심사의 분리
    • 관찰자와 관찰 가능한 객체가 느슨하게 결합되어 있어 독립적으로 유지보수 및 확장이 가능합니다.
  2. 확장성
    • 구독자를 추가하거나 제거하기 쉽고, 이벤트 발생 시 적절한 로직을 동적으로 추가할 수 있습니다.

단점

  1. 성능 문제
    • 구독자 수가 많거나, 각 구독자의 처리 로직이 복잡하면 성능 저하가 발생할 수 있습니다.

주의할 점

  • 구독 해제 처리
    • 구독자가 메모리에 계속 남아있으면 메모리 누수가 발생할 수 있습니다. 이를 방지하려면 구독 해제를 철저히 관리해야 합니다.
  • 구독자 로직 간소화
    • 각 구독자의 이벤트 처리 로직을 최소화하여 성능 문제를 완화합니다.

 

[참고] https://refactoring.guru/ko/design-patterns/observer

반응형