블로그 이미지
윤영식
Full Stacker, Application Architecter, KnowHow Dispenser and Bike Rider

Publication

Category

Recent Post

오브젝트간의 이벤트 전달이 필요할 경우 loose coupling 을 유지하면서 커뮤니케이션이 가능토록 해주는 중재자 패턴에 대해 알아보자 



1) 중재자 패턴

  - 하나의 오브젝트 상태 변경시 다른 오브젝트가 해당 변경 정보를 알아야 할 경우

  - 별도의 중재자를 두어서 해당 중재자가 한 오브젝트의 변화에 대해 관심을 가지고 있는 오브젝트들한테 변경 정보를 전달한다

  

    + Mediator : Colleague 오브젝트와 통신할 수 있는 인터페이스를 정의한다 

    + ConcreteMediator : ConcreteColleagues 오브젝트들의 레퍼런스를 가지고 있다. 정보를 전달해 주는 역할을 수행

    + Colleague classes : Mediator 오브젝트의 레퍼런스를 가지고 있다가 다른 Colleague와 통신하길 원하면  Mediator를 통해서 통신을 한다 


  - 사용예

    + GUI Libraries : GUI 컴포넌트에서 하나가 선택되면 다른 것들이 enable/disable 되는 경우 

    + Chatting Application

       Chatroom : Mediator 로써 참석자들끼리 대화를 중재 인터페이스 정의

       ChatroomImpl : ConcreteMediator 한 참가자가 메세지 보내면 다른 참가들에게 메세지 전송하는 역할을 구현

       Participant : Colleague 참가자 인터페이스 정의

       HumanParticipant, Bot : ConcreteColleague 는 사람이 될 수도 bot이 될 수도 있다. Mediator 레퍼런스를 참조한다다



2) 구현상의 고려사항

  - Mediator 인터페이스정의는 Colleague 들이 여러개의 Mediator가 필요할 경우이다. 한개의 Mediator만 필요하다면 굳이 인터페이스 정의는 필요없다

  - Colleague의 상태가 변하면 정보를 Mediator에 전달하고 해당 정보에 관심이 있는 Colleague에 정보를 전달해 주는 Observer 패턴과 유사하다

  - 정보가 많을 경우 Asynch를 고려한다면 Message Queue 가 필요할 수 있다 

  - Colleague가 많아지면 Mediator 구현체가 복잡해 질 수 있다. 



3) Mediator.js 분석

  - 사이트 : https://github.com/ajacksified/Mediator.js

  - 중재자 패턴을 이용하여 WebSocket, AJAX call, DOM 이벤트를 쉽게 다루고 테스트 할 수 있도록 한다 

  - 채널(Channel)이 중재자가 되어서 Colleague들에게 관심 정보를 전파한다 

  - 설치하기 

$ npm install mediator-js

npm http GET https://registry.npmjs.org/mediator-js

npm http 200 https://registry.npmjs.org/mediator-js/-/mediator-js-0.9.2.tgz

mediator-js@0.9.2 node_modules/mediator-js


  - Node.js에서 사용하기 

////////////////////

// md_node.js 파일

var Mediator = require("mediator-js").Mediator,

    mediator = new Mediator();


mediator.subscribe("wat", function(){ console.log(arguments); });

mediator.publish("wat", 7, "hi dowon", { one: 1 }); 


////////////////////

// 결과 (wat이 채널) 

$ node md_node.js

{ '0': 7,

  '1': 'hi dowon',

  '2': { one: 1 },

  '3':

   { namespace: 'wat',

     _subscribers: [ [Object] ],

     _channels: [],

     _parent:

      { namespace: '',

        _subscribers: [],

        _channels: [Object],

        _parent: undefined,

        stopped: false },

     stopped: false } }


  - 브라우져에서 AMD로 사용하기 

     + require.js 와 mediator.js 파일은 md_browser.html 파일 위치에서 js/ 폴더 밑에 존재함

////////////////////

// md_browser.html

<!doctype html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Test</title>

</head>

<body>


<script src="js/require.js"></script>

<script>

        // base url을 반드시 주어야 한다 

requirejs.config({

   baseUrl: './js/'

});


        // 주의) mediator.js 에서 define을 Mediator 로 M을 대문자로 정의하였다 

require(['Mediator'], function(mediator) {

 mediator.subscribe("wat", function(){ console.log(arguments); });

 mediator.publish("wat", 7, "hi", { one: 1 });

});

</script>


</body>

</html>


   + subscribe/publish API

mediator.subscribe(channel, callback, <options>, <context>);

mediator.publish(channel, <data, data, ... >)

mediator.remove(channel, <identifier>)


   + on/bind 는 subscribe 의 alias 이고, trigger/emit 은 publish 의 alias, off 는 remove의 alias

   + Channel의 Namespace 로 : 를 사용한다 예) application:chat



<참조>

  - http://www.oodesign.com/mediator-pattern.html

  - 3실 청년 설명

  - 예제를 가지고 시퀀스 다이어그램을 통해서 설명

  - 다이어그램 보기 : UML 기초

  - 자바스크립트의 Mediator 패턴 설명

  - 자바스크립트 디자인패턴 - 설명

posted by 윤영식