안녕하세요. 이번 시간에는 명령 패턴에 대해 알아보겠습니다. 명령 패턴은 이름 그대로 명령을 내리는 패턴입니다. 퍼사드 패턴 시간에 갈바가 군단에게 명령을 내리는 것 같이요. 다른 점은 명령이 독립적으로 있기 때문에 얼마든지 새로운 명령을 추가할 수 있다는 점입니다. 또한 undo 메소드를 만들어서 잘못된 명령을 내렸을 때 이전으로 되돌릴 수 있죠. 코드로 보겠습니다.
오토는 갈바를 암살하고 황제의 자리에 올랐지만 그에게는 어두운 미래가 다가오고 있었습니다. 바로 오토가 갈바를 암살하던 때, 비텔리우스는 독일의 군단을 이끌고 로마로 진격하고 있었죠. 오토는 그 사실을 몰랐고요. 때를 참 잘못 탔습니다. 비텔리우스는 휘하 군단에게 로마를 공격하라는 명령을 내립니다. 비텔리우스는 매우 게을렀기 때문에 직접 전술을 짜지 않고, 총사령관인 카이키나가 전술을 짜면 최종 승인만 내렸습니다.
var Vitellius = (function() {
function Vitellius() {}
Vitellius.prototype.approve = function(commander) {
commander.execute();
};
return Vitellius;
})();
var Commander = (function() {
function Commander() {
this.commands = [];
}
Commander.prototype.execute = function() {
this.commands.forEach(function(command) {
command();
});
};
Commander.prototype.do = function(command, args) {
this.commands.push(function() {
command.call(null, args);
});
};
Commander.prototype.undo = function() {
this.commands.pop();
};
return Commander;
})();
var strategy = {
climbAlps: function() {
console.log('알프스를 오릅니다');
},
prepareSupply: function(number) {
console.log('보급품을 ' + number + '만큼 준비합니다');
},
attackRome: function() {
console.log('로마를 공격합니다');
},
};
var vitellius = new Vitellius();
var caecina = new Commander();
caecina.do(strategy.prepareSupply, 5000);
caecina.undo(); // prepareSupply 취소
caecina.do(strategy.prepareSupply, 10000);
caecina.do(strategy.climbAlps);
caecina.do(strategy.attackRome);
vitellius.approve(caecina); // 보급품을 10000만큼 준비합니다. 알프스를 오릅니다. 로마를 공격합니다.
비텔리우스보다 Commander 생성자에 더 주목해주시기 바랍니다. Commander 생서자는 명령을 받거나 되돌리고 최종적으로 비텔리우스의 승인을 받아 명령을 실행합니다. 보통 명령 패턴에서는 한 번에 몰아서 실행하지 않고 그 때 그 때 바로 실행합니다. 하지만 실행 취소를 하는 예시를 들기 위해 조금 수정했습니다.
나중에 명령을 더 추가하고 싶으면 strategy 객체에 추가하면 됩니다. Commander는 명령을 총체적으로 관리하는 객체이고 strategy는 명령을 모아둔 객체입니다. 비텔리우스는 사용자라고 생각하면 됩니다. 사용자가 어떤 동작을 하면(위의 코드처럼 approve 함수를 호출한다든지, 버튼에 이벤트리스너를 연결한 후 버튼을 누른다든지) Commander는 명령을 실행하는 겁니다.
다음 시간에는 책임 연쇄 패턴에 대해서 알아보겠습니다!