이런저런 IT 이야기
article thumbnail
Published 2023. 5. 25. 13:53
Observer 패턴 Javascript
반응형

 

Observer 패턴은 객체 간의 일대다 의존성을 관리하는 패턴입니다. 이 패턴은 한 객체의 상태 변화에 대해 의존하는 다른 객체들(옵저버들)에게 자동으로 알림을 보내고 업데이트를 수행할 수 있는 기능을 제공합니다.

Observer 패턴은 객체 간의 결합도를 줄이고 유연성을 높이는데 사용됩니다. 옵저버들은 주체(Subject) 객체의 변화에 대해 관찰하고, 주체 객체의 상태가 변경되면 알림을 받아 업데이트를 수행할 수 있습니다. 이를 통해 객체 간의 상호작용을 느슨하게 결합시킬 수 있습니다.

그림 1

JavaScript에서 Observer 패턴을 구현하기 위해 주로 사용되는 방법은 다음과 같습니다:

  1. 주체(Subject): 상태 변화를 감지하고 옵저버들에게 알림을 보내는 객체입니다. 주체 객체는 옵저버들을 등록 및 관리하며, 상태 변화가 발생하면 등록된 옵저버들에게 알림을 보냅니다.
  2. 옵저버(Observer): 주체 객체의 상태 변화에 대해 관찰하고 업데이트를 수행하는 객체입니다. 옵저버들은 주체 객체에 등록되어야 하며, 상태 변화가 발생하면 주체 객체로부터 알림을 받아 업데이트 작업을 수행합니다.

 

예를 들어, 다음은 JavaScript에서 Observer 패턴을 사용하여 상태 변화를 감지하고 알림을 받는 예제입니다:

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

  addObserver(observer) {
    this.observers.push(observer);
  }

  removeObserver(observer) {
    this.observers = this.observers.filter((obs) => obs !== observer);
  }

  notifyObservers() {
    for (const observer of this.observers) {
      observer.update();
    }
  }

  // 주체 객체의 상태 변화가 발생할 때마다 호출됨
  changeState() {
    console.log('Subject: State changed');
    this.notifyObservers();
  }
}

class Observer {
  constructor(name) {
    this.name = name;
  }

  update() {
    console.log(`Observer ${this.name}: Received update`);
  }
}

// 주체 객체 생성
const subject = new Subject();

// 옵저버 객체 생성
const observer1 = new Observer('Observer 1');
const observer2 = new Observer('Observer 2');

// 옵저버 등록
subject.addObserver(observer1);
subject.addObserver(observer2);

// 주체 객체의 상태 변화 발생
subject.changeState();

위의 예제에서 Subject 클래스는 주체 객체를 나타내며, Observer 클래스는 옵저버 객체를 나타냅니다. Subject 객체는 옵저버들을 등록하고 상태 변화가 발생하면 notifyObservers()를 호출하여 등록된 옵저버들에게 알림을 보냅니다. Observer 객체는 update() 메서드를 통해 알림을 받고 업데이트 작업을 수행합니다.

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

  subscribe(eventName, observer) {
    if (!this.observers[eventName]) {
      this.observers[eventName] = [];
    }
    this.observers[eventName].push(observer);
  }

  unsubscribe(eventName, observer) {
    if (this.observers[eventName]) {
      this.observers[eventName] = this.observers[eventName].filter(
        (obs) => obs !== observer
      );
    }
  }

  publish(eventName, data) {
    if (this.observers[eventName]) {
      this.observers[eventName].forEach((observer) => {
        observer.update(data);
      });
    }
  }
}

class EventListener {
  constructor(name) {
    this.name = name;
  }

  update(data) {
    console.log(`EventListener ${this.name}: Received event ${data}`);
  }
}

// 이벤트 옵저버 객체 생성
const eventObserver = new EventObserver();

// 이벤트 리스너 객체 생성
const listener1 = new EventListener('Listener 1');
const listener2 = new EventListener('Listener 2');
const listener3 = new EventListener('Listener 3');

// 이벤트 구독
eventObserver.subscribe('click', listener1);
eventObserver.subscribe('click', listener2);
eventObserver.subscribe('mouseover', listener2);
eventObserver.subscribe('keypress', listener3);

// 이벤트 발행
eventObserver.publish('click', 'Button clicked');
eventObserver.publish('mouseover', 'Mouse hovered');
eventObserver.publish('keypress', 'Key pressed');

// 이벤트 구독 해제
eventObserver.unsubscribe('click', listener2);

// 이벤트 발행
eventObserver.publish('click', 'Button clicked');

위의 예제에서 EventObserver 클래스는 이벤트 옵저버를 관리하는 역할을 수행합니다. subscribe 메서드를 사용하여 이벤트에 옵저버를 구독하고, unsubscribe 메서드로 구독을 해제할 수 있습니다. publish 메서드를 통해 이벤트를 발행하면 구독된 옵저버들에게 알림이 전달됩니다.

EventListener 클래스는 이벤트를 구독하는 옵저버를 나타냅니다. update 메서드를 통해 이벤트 발생 시 알림을 받고 처리합니다.

위의 예제에서는 'click', 'mouseover', 'keypress'와 같은 다양한 이벤트를 구독하고 발행하는 방식으로 Observer 패턴을 구현하였습니다. 이를 통해 이벤트와 관련된 동작을 모듈화하고 컴포넌트 간의 결합도를 낮출 수 있습니다.

옵저버 패턴은 객체 간의 느슨한 결합을 제공하며, 주체 객체와 옵저버들 사이의 상호작용을 관리하는 데 유용합니다. 이를 통해 코드의 유연성과 확장성을 향상시킬 수 있습니다.

반응형

'Javascript' 카테고리의 다른 글

JavaScript 메모리 관리 Heap(힙)과 Stack(스택)  (0) 2023.05.25
Module 패턴  (0) 2023.05.25
Proxy 패턴  (0) 2023.05.25
[Javascript] Sort, Splice, Slice 정리  (0) 2023.05.24
[Javascript] Filter, Reduce, Map 응용  (0) 2023.05.23
profile

이런저런 IT 이야기

@이런저런 IT 이야기

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

profile on loading

Loading...

검색 태그