게시글

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

디자인 패턴(책임 연쇄, chain of responsibility)

안녕하세요. 이번 시간에는 책임 연쇄 패턴에 대해 알아보겠습니다. 책임 연쇄라고 하니 뭔가 거창하게 들리지만 사실 별 거 없습니다. 동작의 수행을 다른 객체에게 떠넘기는 패턴일 뿐입니다. 가장 쉽게 접하는 예로 이벤트 버블링이 있습니다. 어떤 태그에 이벤트가 발생하면 그 이벤트는 해당 태그의 부모나 조상에게도 순서대로 발생합니다. 이 때 사용자가 이벤트 리스너를 달아서 어떤 태그에서 이벤트를 처리할 지, 또는 다음 태그로 이벤트 처리 수행을 넘길지 결정할 수 있습니다. 이와 같이 동작의 처리를 자신이 할 지 다음으로 넘길 지 결정하는 패턴이 책임 연쇄입니다.

비텔리우스가 오토의 군단을 격파하며 로마로 진격하자 로마는 큰 혼란에 휩싸였습니다. 항복을 해야할 지 맞서 싸울 지를 두고 의견이 분분했죠. 장군들은 쉽사리 결정을 내리지 못했습니다. 그래서 원로원에 결정권을 넘겼습니다. 하지만 역시 원로원에서도 의견이 갈려 결정하지 못했죠. 원로원에서 결단을 내리지 못하자, 황제인 오토가 직접 결단을 내립니다.

var General = (function() {
  function General() {}
  General.prototype.canMakeDecision = function() {
    // 복잡한 확인 코드
    return false;
  };
  General.prototype.makeDecision = function() {
    console.log('맞서 싸운다');
  };
  return General;
})();
var Senator = (function() {
  function Senator() {}
  Senator.prototype.canMakeDecision = function() {
    // 복잡한 확인 코드
    return false;
  };
  Senator.prototype.makeDecision = function() {
    console.log('눈치를 본다');
  };
  return Senator;
})();
var Emperor = (function() {
  function Emperor() {}
  Emperor.prototype.canMakeDecision = function() {
    // 복잡한 확인 코드
    return true;
  };
  Emperor.prototype.makeDecision = function() {
    console.log('항복한다');
    console.log('자결한다');
  };
  return Emperor;
})();
var DecisionMaker = (function() {
  function DecisionMaker() {
    this.decisionMakers = [];
    this.decisionMakers.push(new General());
    this.decisionMakers.push(new Senator());
    this.decisionMakers.push(new Emperor());
  }
  DecisionMaker.prototype.makeDecision = function() {
    for (var i = 0; i < this.decisionMakers.length; i++) {
      if (this.decisionMakers[i].canMakeDecision()) {
        return this.decisionMakers[i].makeDecision();
      }
    }
  };
  return DecisionMaker;
})();
var choice = new DecisionMaker();
choice.makeDecision(); // 항복한다 자결한다

코드를 보면 결정의 주체가 세 종류가 있습니다. 장군, 원로원, 황제죠. 각각 canMakeDecision과 makeDecision 메소드를 가지고 있습니다. 전자는 결정을 내릴 수 있는지 여부를 판단하고, 후자는 결정을 내립니다. 장군과 원로원은 canMakeDecision은 false를 return하기 때문에 결정을 내릴 수 없습니다. 저는 간단하게 바로 return false를 했지만, 내부 구현은 알아서 하시면 됩니다.

DecisonMaker 생성자를 보면 makeDecision을 통해 장군, 원로원, 황제 순서대로 결정을 내릴 수 있는지를 판단하고, 결정을 내릴 수 있으면 결정을 내리고 종료합니다. 아까 장군과 원로원은 결정을 내릴 수 없었기 때문에 황제가 결정을 내리게 됩니다. (황제는 return true를 했습니다. 이 부분도 내부는 직접 구현하시면 됩니다) 결국 최종적으로 this.decisionMakers[i]는 황제가 되어 황제의 makeDecision 메소드가 호출됩니다.

이렇게 책임을 다음 순서에게 떠넘기기 때문에 책임 연쇄 패턴이라고 이름지어졌습니다. 또한 중간 단계의 누군가가 책임을 처리하면 다음 순번에게는 넘어가지 않죠. 황제 오토는 승산이 없음을 직감하고 로마 제국이 더이상의 혼란에 휩싸이지 않도록 항복을 선택하고 자결합니다. 비텔리우스는 쉽사리 로마로 입성해서 황제에 등극합니다. 오토는 나중에 로마를 위해 자결한 것으로 평가받아 권위가 회복됩니다.

다음 시간에는 반복자 패턴에 대해 알아보겠습니다!

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

댓글

1개의 댓글이 있습니다.
7년 전
엠페러객체 내부의 프로토타입 지정 대상이 제너럴로 되어있네요 확인 부탁드릴께요~
7년 전
감사합니다~