본문 바로가기
반응형
Programming/Javascript

자바스크립트(Javascript) 디자인 패턴 - 감시자/옵저버(Observer) 패턴

by JAMINS 2020. 6. 3.

디자인패턴을 공부하면서 정리했던 옵저버 패턴 에 이어 이번엔 자바스크립트로 구현하는 방법에 대해서 알아본다. 옵저버 패턴의 정의와 Java로 구현하는 방법은 이 링크에 정리해두었다.

클릭과 같은 이벤트를 받아 전달할 때, 알려야하는 객체들에게 변경사항을 알릴 때 Publisher/Subscriber 패턴이라고 한다. MQTT같은 메시지 프로토콜에서 사용되는 패턴으로 주로 사용되는데 이 또한 옵저버 패턴이라 말할 수 있다. 주요 목적은 객체간의 결합도를 낮추기 위함이다. Publisher는 구독자 즉, 감시자(Observer) 가 되고 관찰되는 객체는 발행자, 감시대상(subject).

예시 (잡지 구독)

잡지 구독을 예시로 들어보자. 잡지를 구독한 사람들에게 잡지를 발행 할 때마다 알려준다.

  • subscriber : 구독자
  • publisher : 발행자

두 종류가 있고 발행자는 구독자들의 목록을 가지고 있어야 한다. 발행자가 가지고 있어야할 정보와 메서드 목록을 보면,

  • subscribers : 구독한 사람들의 목록(장부)
  • subscribe() : 구독 요청. 목록에 추가
  • unsubscribe() : 구독 취소, 목록에서 제거
  • publish() : 구독자들에게 알림

구현

Publisher

var publisher = {
    // 구독자 목록
    subscribers: {
        any: []
    },

    subscribe: function(fn, type) {
        ..
        this.subscribers[type].push(fn);
    },
    unsubscribe: function(fn, type) {
        ..
        this.subscribers[type].
    },
    publish: function(publication, type) {
        ...
        this.visitSubscribers('publish', publication, type);
    },
    visitSubscribers: function(action, arg, type) {
        ...

        // publish 역할을 하거나
        // unsubscribe하는 자를 찾아 목록에서 제거
        for (i = 0; i < max; i++) {
            if (action == 'publish') {
                subscribers[i](arg);
            } else {
                if (subscribers[i] === arg) {
                    subscribers.splice(i, 1);
                }
            }
        }
    }    
};

구현 후 객체를 받아 publisher 의 메서드들을 복사하여 발행자 객체로 변경한다.

function makePublisher(o) {
    var i;
    for (i in publisher) {
        if(publisher.hasOwnProperty(i) && ..) {
            o[i] = publisher[i];
        }
    }
    o.subscribers = {any: []};
}

Paper 라는 객체를 생성하여 makePublisher로 변경하면 된다.

Subscriber

구독자를 별도로 만든다.

var jane = {
    drinkCoffee: function(paper) {
        // TODO:
    },
    sundayPreNam: function(monthly) {
        // TODO:
    }
};
paper.subscribe(jane.drinkCoffee);
paper.subscribe(jane.sundayPreNam, 'monthly');

이와 같이 paper의 구독자 목록에 jane을 추가한다. jane뿐만 아니라 느슨하게 수많은 구독자를 추가할 수 있다.

중재자 패턴과의 다른점

이전글 : 중재자 패턴

중재자 객체가 다른 객체에 대해 정확히 알아야만 했다. 즉 결합도가 높아질 수 밖에없는데, 옵저버 패턴은 객체를 알지 않아도 된다. 결합도를 낮춘다. 또한, 절차적인 방법 보단 Event driven에 가깝다.

참고

  • 자바스크립트 디자인패턴 책

댓글