안녕하세요. 이번 시간에는 옵저버 패턴 또는 관찰자 패턴에 대해서 알아보겠습니다. 옵저버는 스타크래프트에 있는 그 옵저버가 맞습니다. 항상 어딘가에서 여러분을 관찰하고 있죠.
브라우저에도 똑같은 역할을 하는 게 있습니다. 바로 이벤트 핸들러죠. 이벤트를 등록만 해 두면, 나중에 이벤트가 발생했을 때 알려줍니다. 그 후에는 콜백 함수가 실행됩니다. 다시 말하면, 콜백 함수가 실행되기 전까지의 과정이 바로 옵저버 패턴을 활용한 예라고 할 수 있습니다.
시리아 총독이었던 무키아누스는 항상 주변 상황과 인물들을 주의깊게 살펴보고 있었습니다. 옆 지방 사령관 베스파시아누스도 그의 관찰 대상 중 하나였죠. 그가 무슨 행동을 할 때마다 무키아누스는 그에 대한 소식을 들으며 나름대로의 평가를 내리고 있었죠. 여러가지 소식을 종합한 후, 무키아누스는 베스파시아누스가 상당히 괜찮은 인물이라고 생각하게 되었습니다. 그 때 마침 오토를 따르던 도나우 군단이 무키아누스를 황제로 추대합니다. 야욕이 없던 무키아누스는 그 간의 평가를 바탕으로 베스파시아누스를 황제로 추대합니다. 베스파시아누스가 행동 하나 하나로 무키아누스에게 점수를 따는 것을 코드로 만들어보겠습니다.
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 }]
코드를 보면 publish와 subscribe 그리고 fire 메소드가 있습니다. 먼저 관찰 대상을 subscribe한 후, 관찰 대상은 특정 행동을 할 때 자신의 행동을 publish합니다. publish한 행동은 subscribe한 사람들에게 전달됩니다. 그 전달 방식이 fire입니다. fire 부분은 콜백이라고 보셔도 됩니다. 무키아누스가 베스파시아누스를 관찰하고 있다가, 베스파시아누스가 특정 행동을 하니까 자동으로 무키아누스에게 그 소식이 전달됩니다. 베스파시아누스가 1점을 딴 것을 확인할 수 있습니다.
다음 시간에는 마지막 디자인 패턴으로 전략 패턴에 대해 알아보겠습니다!