게시글

5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭
강좌47 - JavaScript - 8년 전 등록 / 6년 전 수정

디자인 패턴(관찰자, 옵저버, observer)

안녕하세요. 이번 시간에는 옵저버 패턴 또는 관찰자 패턴에 대해서 알아보겠습니다. 옵저버는 스타크래프트에 있는 그 옵저버가 맞습니다. 항상 어딘가에서 여러분을 관찰하고 있죠.

브라우저에도 똑같은 역할을 하는 게 있습니다. 바로 이벤트 핸들러죠. 이벤트를 등록만 해 두면, 나중에 이벤트가 발생했을 때 알려줍니다. 그 후에는 콜백 함수가 실행됩니다. 다시 말하면, 콜백 함수가 실행되기 전까지의 과정이 바로 옵저버 패턴을 활용한 예라고 할 수 있습니다.

시리아 총독이었던 무키아누스는 항상 주변 상황과 인물들을 주의깊게 살펴보고 있었습니다. 옆 지방 사령관 베스파시아누스도 그의 관찰 대상 중 하나였죠. 그가 무슨 행동을 할 때마다 무키아누스는 그에 대한 소식을 들으며 나름대로의 평가를 내리고 있었죠. 여러가지 소식을 종합한 후, 무키아누스는 베스파시아누스가 상당히 괜찮은 인물이라고 생각하게 되었습니다. 그 때 마침 오토를 따르던 도나우 군단이 무키아누스를 황제로 추대합니다. 야욕이 없던 무키아누스는 그 간의 평가를 바탕으로 베스파시아누스를 황제로 추대합니다. 베스파시아누스가 행동 하나 하나로 무키아누스에게 점수를 따는 것을 코드로 만들어보겠습니다.

var Vespasianus = (function() {
  function Vespasianus() {
    this.subscribers = [];
  }
  Vespasianus.prototype.publish = function() {
    var self = this;
    this.subscribers.every(function(subscriber) {
      subscriber.fire(self);
      return true;
    });
  };
  Vespasianus.prototype.register = function(target) {
    this.subscribers.push(target);
  };
  return Vespasianus;
})();

var Mucianus = (function() {
  function Mucianus() {
    this.list = [];
  }
  Mucianus.prototype.subscribe = function(target) {
    this.list.push({
      target: target,
      point: 0,
    });
    target.register(this);
  };
  Mucianus.prototype.unsubscribe = function(target) {
    this.list = this.list.filter(function(person) {
      return person.target !== target;
    });
  };
  Mucianus.prototype.fire = function(target) {
    this.list.some(function(person) {
      console.log(person.target, target, person.target === target);
      if (person.target === target) {
        ++person.point;
        return true;
      }
    });
  };
  return Mucianus;
})();
var vespasianus = new Vespasianus();
var mucianus = new Mucianus();
mucianus.subscribe(vespasianus);
vespasianus.publish();
mucianus.list; // [{ target: Vespasianus, point: 1 }]

코드를 보면 publishsubscribe 그리고 fire 메소드가 있습니다. 먼저 관찰 대상을 subscribe한 후, 관찰 대상은 특정 행동을 할 때 자신의 행동을 publish합니다. publish한 행동은 subscribe한 사람들에게 전달됩니다. 그 전달 방식이 fire입니다. fire 부분은 콜백이라고 보셔도 됩니다. 무키아누스가 베스파시아누스를 관찰하고 있다가, 베스파시아누스가 특정 행동을 하니까 자동으로 무키아누스에게 그 소식이 전달됩니다. 베스파시아누스가 1점을 딴 것을 확인할 수 있습니다.

다음 시간에는 마지막 디자인 패턴으로 전략 패턴에 대해 알아보겠습니다!

조회수:
0
목록
투표로 게시글에 관해 피드백을 해주시면 게시글 수정 시 반영됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright 2016- . 무단 전재 및 재배포 금지. 출처 표기 시 인용 가능.
5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭

댓글

3개의 댓글이 있습니다.
4년 전
every 를 사용한 이유가 뭘까요? 그냥 subscribers.forEach 로 fire를 호출해도 결과는 같더라구요. every와 some의 용도를 추측하기가 어렵네요 ㅠ
4년 전
every는 return false 시 종료되고 some은 return true 시 종료됩니다. 지금보니 every는 의미가 없네요. forEach 쓰면 되겠습니다.
6년 전
28열의 필터의 결과를 리턴을 안하는데 어떻게 기능하죠? 필터는 원본 배열을 수정하지 않아서 반드시 결과를 받아야하는데요
6년 전
아 수정했습니다. 감사합니다.
6년 전
배열의 매소드인, Array.prototype.every(), Array.prototype.filter(), Array.prototype.some() 에 대한 내용(기본설명, 사용한 이유)도 같이 있으면 이해하기 쉬울거 같아요!!