Design Pattern

Command Pattern, 커맨트 패턴

iKay 2020. 4. 13. 23:21
반응형

커맨트 패턴은 이벤트가 발생했을 때 실행될 기능이 다양하면서도 변경이 필요한 경우에 이벤트를 발생시키는 클래스를 변경하지 않고 재사용할 때 유용하다.

 

 

아래 타입스크립트 코드를 보자.

 

예를 들어, 스타크래프트에서 attack 버튼과 move 버튼이 있을 경우, attack, move 등의 기능을 수정하기 위해 button 클래스를 직접 수정해야 해서 즉, onPressed 메소드를 수정해야 하므로 OCP를 위반하게 되는 것이다.  

 

type Command = 'attack' | 'move';

class Button {
    private attack: Attack;
    private move: Move;
    private command: Command;

    constructor(command: Command) {
        this.attack = new Attack();
        this.move = new Move();
        this.command = command;
    }

    setCommand(command: Command) {
        this.command = command;
    }

    onPressed() {
        switch (this.command) {
            case 'attack':
                this.attack.fire();
                return;

            case 'move':
                this.move.go();
                return;
        }
    }
}

class Attack {
    fire() {
        console.log('Attack!');
    }
}

class Move {
    go() {
        console.log('Go Go Go!!');
    }
}

function Main() {
    const button = new Button('attack');
    button.onPressed(); // Attack!

    button.setCommand('move');
    button.onPressed(); // Go Go Go!!
}

Main();

 

하지만 다음과 같이 button을 누를 때 button.onPressed() 메소드 하나만으로 어떠한 클래스 수정없이 move와 attack을 변경하면서 사용할 수 있다.

 

 

 

 

interface Command {
    execute(): void;
}

class Button {
    constructor(private command: Command) {}

    setCommand(command: Command) {
        this.command = command;
    }

    onPressed() {
        this.command.execute();
    }
}

class AttackCommand implements Command {
    constructor(private attack = new Attack()) {}

    execute(): void {
        this.attack.fire();
    }
}

class Attack {
    fire() {
        console.log('Attack!');
    }
}

class MoveCommand implements Command {
    constructor(private move = new Move()) {}

    execute(): void {
        this.move.go();
    }
}

class Move {
    go() {
        console.log('Go Go Go!!');
    }
}

function Main() {
    const button = new Button(new AttackCommand());
    button.onPressed(); // Attack!

    button.setCommand(new MoveCommand());
    button.onPressed(); // Go Go Go!!
}

Main();

 

결론

command pattern과 strategy pattern은 메소드 실제 행위를 다른 객체에 위임한다는 점에서 매우 비슷한 디자인 패턴인 것 같다. 유일한 다른 점은 command pattern의 경우 receiver가 따로 있고 실제 로직을 이 receiver 객체에 구현한다는 점인것 같다. 다시 말해, Command를 implement한 클래스 구현체에 로직을 직접 구현하지 않고, 로직이 구현되는 객체를 따로 둔다는 점인 것 같다. strategy pattern의 경우 implement한 클래스에서 바로 로직을 구현한다.

 

궁금한 것이 있는데 command pattern은 strategy에 비해 어떤 점이 더 좋다고 볼 수 있을까?

반응형

'Design Pattern' 카테고리의 다른 글

Observer pattern, 옵저버 패턴  (0) 2020.05.18
State pattern, 스테이트 패턴  (0) 2020.04.28
Singleton pattern, 싱글톤 패턴  (0) 2020.04.02
Strategy pattern, 스트레이티지 패턴  (0) 2020.04.01