오브젝트간의 이벤트 전달이 필요할 경우 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 기초
'Lean Agile Culture > Architecturing' 카테고리의 다른 글
[아키텍쳐] A Full Javascript Architecture - NodeJS (1) (0) | 2013.02.06 |
---|---|
[기술셋] Backbone.js Node.js MongoDB를 이용한 Web Application 개발 (0) | 2013.01.31 |
[아키테쳐링] Netflix SlideShare (0) | 2012.12.10 |
[아키텍쳐링] Evernote SlideShare (0) | 2012.12.10 |
대용량 아키텍쳐 설계 엔지니어 되기 (0) | 2012.11.20 |