디자인패턴

커맨드 패턴 (Command Pattern)

JUNGKEUNG 2022. 10. 8. 17:55
반응형

커맨드 패턴 이란?

Client가 보낸 요청을 객체로 캡슐화하여 이를 나중에 이용할 수 있도록 필요한 정보를 저장, 로깅, 취소할 수 있게 하는 패턴

요청을 캡슐화 하여 호출자(invoker)와 수신자(reveiver)를 분리하는 패턴이다.

- 요청을 처리하는 방법이 바뀌더라도, 호출자의 코드는 변경되지 않는다

 

 

구성요소

1. 수신자(Receiver) : 행동을 담당하는 객체 -> 기능을 수행

2. 커맨드(Command) : 수신자의 정보 + 행동이 들어있는 객체

3. 호출자(invoker) : 커맨드를 저장하는 객체 -> 버튼이 어떤 수행을 할 것인지 결정

4. 클라이언트(Client) : 커맨드 객체를 생성하고, 호출자를 통해 수신자에게 할 행동을 결정

 

예제 코드


1.Button, MyApp 호출자 (invoker)에 해당된다

public class Button {

    private Light light;

    public Button(Light light){
        this.light = light;
    }

    public void press() {
        light.off();
    }

    public static void main(String [] args) {
        Button button = new Button(new Light());
        button.press ();
        button.press ();
        button.press ();
        button.press ();
    }
}
public class MyApp {

    private Game game;

    public MyApp(Game game){
        this.game = game;
    }

    public void press() {
        game.start();
    }

    public static void main(String [] args) {
        MyApp myApp = new MyApp(new Game());
        myApp.press ();
        myApp.press ();
        myApp.press ();
        myApp.press ();
    }
}

 

2. Game. Light 수신자(receiver)에 해당된다

public class Game {

    private boolean isStarted;

    public void start() {
        System.out.println ("게임을 시작합니다.");
        this.isStarted = true;
    }

    public void end() {
        System.out.println ("게임을 종료합니다.");
        this.isStarted = false;
    }

    public boolean isStarted() {
        return isStarted;
    }
}

public class Light {

    private boolean isOn;

    public void on() {
        System.out.println ("불을 켭니다.");
        this.isOn = true;
    }

    public void off() {
        System.out.println ("불좀 꺼줄래.");
        this.isOn = false;
    }

    public boolean isStarted() {
        return isOn;
    }
}

 

3. invoker코드는 최대한 유지하고 수신자(receiver) 코드만 수정하여 invoker에 적용하자

public interface Command {

    void execute();
}

public class Button {

    private Command command;

    public Button(Command command) {
        this.command = command;
    }

    public void press(){
        command.execute();
    }

    public static void main(String[] args) {
        Button button = new Button(new LightOffCommand(new Light()));
        button.press();
        button.press();
        button.press();
    }
}

public class GameEndCommand implements Command{

    private Game game;

    public GameEndCommand(Game game) {
        this.game = game;
    }

    @Override
    public void execute() {
        game.end();
    }
}

public class GameStartCommand implements Command{

    private Game game;

    public GameStartCommand(Game game) {
        this.game = game;
    }

    @Override
    public void execute() {
        game.start();
    }
}
public class LightOffCommand implements Command{

    private Light light;

    public LightOffCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.off();
    }
}

public class LightOnCommand implements Command{

    private Light light;

    public LightOnCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.on();
    }
}

 

 

장점

  • 기존 코드를 변경하지 않고 새로운 커맨드를 만들 수 있다
  • 수신자의 코드가 변경되어도 호출자의 코드는 변경되지 않는다.
  • 커맨드 객체를 로깅, DB에 저장, 네트워크로 전송하는 등 다양한 방법으로 활용할 수도 있다

단점

  • 코드가 복잡하고 클래스가 많아진다

 

 

Script


커맨드 패턴(Command Pattern)은 Client가 보낸 요청을 객체로 캡슐화하여 이를 나중에 이용할 수 있도록 필요한 정보를 저장, 로깅, 취소할 수 있게 하는 패턴

 

 

참고


 

코딩으로 학습하는 GoF의 디자인 패턴 - 인프런 | 강의

디자인 패턴을 알고 있다면 스프링 뿐 아니라 여러 다양한 기술 및 프로그래밍 언어도 보다 쉽게 학습할 수 있습니다. 또한, 보다 유연하고 재사용성이 뛰어난 객체 지향 소프트웨어를 개발할

www.inflearn.com