자바스크립트 옵져버 패턴(Observer Pattern) 구현
Javascript 2012. 7. 3. 18:23
Observer Pattern
흔히 발행/구독 패턴이라 불리는 이 패턴은 객체의 상태 변화를 관찰하는 관찰자(옵져버)를 객체에 등록(구독)하여, 객체에 상태 변화가 있을때마다 등록된 목록의 관찰자들에게 통지(발행) 하도록 하는 디자인 패턴이다.
쉽게 말해 Broadcast System을 구축할 수 있으며, 각 모듈간의 밀접한 커플링을 조율하여, 모듈의 재사용성을 높인다.
아래 코드는 모든 유저(user1, user2, user3)가 현재 까지 등록(구독)된 유저 현황에 대한 정보를 통지(발행)를 받을 수 있다.
-
// 옵져버 패턴
-
var Observer = new (function () {
-
-
var Observer = function () {
-
this.observers = [];
-
return this;
-
}
-
-
Observer.fn = Observer.prototype = {
-
-
subscribe: function (type, fn) {
-
-
type = type || '';
-
-
this.observers.push({ id: this.observers.length - 1, type: type, fn: fn, isStop: false });
-
-
return (this.observers.length - 1);
-
},
-
remove: function (type, id) {
-
-
type = type || '';
-
-
if (typeof id === 'number') {
-
this.observers[id].type === type && delete this.observers[id];
-
}
-
else {
-
for (var t in this.observers) {
-
if (type) {
-
if (this.observers[t].type === type) {
-
delete this.observers[t];
-
}
-
}
-
else {
-
delete this.observers[t];
-
}
-
}
-
}
-
-
return this;
-
},
-
abort: function (type, id) {
-
-
type = type || '';
-
-
if (typeof id === 'number') {
-
if (this.observers[id].type === type) this.observers[id].isStop = true;
-
}
-
else {
-
for (var t in this.observers) {
-
if (type) {
-
if (this.observers[t].type === type) {
-
this.observers[t].isStop = true;
-
}
-
}
-
else {
-
this.observers[t].isStop = true;
-
}
-
}
-
}
-
-
return this;
-
},
-
restore: function (type, id) {
-
-
type = type || '';
-
-
if (typeof id === 'number') {
-
if (this.observers[id].type === type) this.observers[id].isStop = false;
-
}
-
else {
-
for (var t in this.observers) {
-
if (type) {
-
if (this.observers[t].type === type) {
-
this.observers[t].isStop = false;
-
}
-
}
-
else {
-
this.observers[t].isStop = false;
-
}
-
}
-
}
-
-
return this;
-
},
-
publish: function (type, id) {
-
-
type = type || '';
-
-
if (typeof id === 'number') {
-
typeof this.observers[id].fn === 'function' && this.observers[id].fn.apply(this.observers[id].type, Array.prototype.slice.call(arguments));
-
}
-
else {
-
for (var t in this.observers) {
-
if (type) {
-
if (this.observers[t].type === type && !this.observers[t].isStop) {
-
typeof this.observers[t].fn === 'function' && this.observers[t].fn.apply(this.observers[t].type, Array.prototype.slice.call(arguments));
-
}
-
}
-
else {
-
if (!this.observers[t].isStop) {
-
typeof this.observers[t].fn === 'function' && this.observers[t].fn.apply(this.observers[t].type, Array.prototype.slice.call(arguments));
-
}
-
}
-
}
-
}
-
-
return this;
-
}
-
}
-
-
function marge() {
-
-
var parent = this
-
, target = {};
-
-
for (var i = 0, length = arguments.length; i < length; i++) {
-
-
target = arguments[i];
-
-
for (var n in parent) {
-
if (typeof target[n] === 'undefined') target[n] = parent[n];
-
}
-
}
-
-
return target;
-
}
-
-
return Observer;
-
-
} ())();
-
-
function Users(name, callback) {
-
this.name = name;
-
-
Observer.subscribe(this, callback);
-
-
return this;
-
}
-
-
Users.prototype.broadCast = function () {
-
alert(this.name + '님 안녕하세요.');
-
}
-
-
var user1 = new Users('전성균1', Users.prototype.broadCast);
-
var user2 = new Users('전성균2', Users.prototype.broadCast);
-
var user3 = new Users('전성균3', Users.prototype.broadCast);
-
var uid = Observer.subscribe(user3, Users.prototype.broadCast);
-
-
// 구독 삭제
-
//Observer.remove();
-
//Observer.remove(user1);
-
//Observer.remove(user3, uid);
-
-
// 구독 정지
-
//Observer.abort();
-
//Observer.abort(user3);
-
//Observer.abort(user3, uid);
-
-
// 구독 복구
-
//Observer.restore();
-
//Observer.restore(user3);
-
//Observer.restore(user3, uid);
-
-
// 통지
-
//Observer.publish();
-
//Observer.publish(user3);
-
//Observer.publish(user3, uid);