본문 바로가기

JAVA/디자인 패턴

[Design Pattern] Command(커맨드) 패턴이란?

반응형
행위 패턴(Behavioral Pattern)


커맨드 패턴(Command Pattern)은 객체 지향 디자인 패턴 중 하나로, 요청을 객체의 형태로 캡슐화하여 나중에 실행하거나 취소할 수 있는 연산을 지원합니다.

이 패턴에서는 요청을 발신하는 객체와 요청을 수행하는 객체 사이에 인터페이스를 정의하고, 이를 통해 서로를 분리합니다. 이를 통해 요청을 실행하는 객체는 어떤 요청이 언제 수행되어야 하는지 알 필요 없이 요청을 수행할 수 있습니다.

커맨드 패턴은 다음과 같은 요소로 이루어져 있습니다.

 

  1. 커맨드(Command): 요청을 나타내는 객체입니다. 보통 execute()라는 메서드를 갖고 있으며, 이 메서드를 호출하면 요청이 수행됩니다.
  2. 컨크리트 커맨드(Concrete Command): 커맨드의 구체적인 구현입니다.
  3. 인보커(Invoker): 요청을 발신하는 객체입니다. 보통 커맨드 객체를 생성하고 execute() 메서드를 호출하여 요청을 수행합니다.
  4. 수신자(Receiver): 요청을 수행하는 객체입니다. 이 객체는 커맨드 객체에서 요청을 처리하는데 필요한 실제 작업을 수행합니다.
  5. 클라이언트(Client): 인보커 객체와 수신자 객체 사이에서 커맨드 객체를 생성하고 설정합니다.

커맨드 패턴을 사용하면 요청과 수신자를 분리하여, 요청을 수행하는 객체가 수신자의 내부 상태를 변경하지 않고 요청을 수행할 수 있습니다. 이를 통해 코드의 결합도를 낮추고 유연성을 높일 수 있습니다. 또한, 커맨드 객체를 로깅, 취소, 다시 실행하는 등의 추가적인 기능을 제공할 수 있습니다.

 

 

Command 패턴 예제

Diagrams

자바에서 커맨드 패턴을 구현해보겠습니다. 예제로는 스마트홈에서 램프를 켜고 끄는 기능을 구현해보겠습니다.

 

 

먼저, 커맨드(Command) 인터페이스를 정의합니다.

public interface Command {
    void execute();
}



다음으로는 컨크리트 커맨드(Concrete Command)를 정의합니다. 램프를 켜는 LampOnCommand와 끄는 LampOffCommand를 구현해보겠습니다.

public class LampOnCommand implements Command {
    private Lamp lamp;

    public LampOnCommand(Lamp lamp) {
        this.lamp = lamp;
    }

    @Override
    public void execute() {
        lamp.turnOn();
    }
}

public class LampOffCommand implements Command {
    private Lamp lamp;

    public LampOffCommand(Lamp lamp) {
        this.lamp = lamp;
    }

    @Override
    public void execute() {
        lamp.turnOff();
    }
}



LampOnCommand와 LampOffCommand는 Lamp 객체를 필드로 가지며, execute() 메서드에서 각각 램프를 켜고 끕니다.

다음으로는 인보커(Invoker)를 정의합니다. 인보커는 Command 객체를 가지며, execute() 메서드를 통해 Command를 실행합니다.

public class RemoteControl {
    private Command command;

    public void setCommand(Command command) {
        this.command = command;
    }

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



마지막으로는 수신자(Receiver)인 Lamp 객체를 정의합니다.

public class Lamp {
    private boolean isOn;

    public void turnOn() {
        isOn = true;
        System.out.println("Lamp is on");
    }

    public void turnOff() {
        isOn = false;
        System.out.println("Lamp is off");
    }
}



이제 메인 클래스에서 RemoteControl 객체를 생성하고, 각각의 Command를 생성하여 setCommand() 메서드를 호출합니다.

public class Main {
    public static void main(String[] args) {
        Lamp lamp = new Lamp();
        RemoteControl remote = new RemoteControl();

        Command lampOnCommand = new LampOnCommand(lamp);
        Command lampOffCommand = new LampOffCommand(lamp);

        remote.setCommand(lampOnCommand);
        remote.buttonPressed(); // "Lamp is on" 출력

        remote.setCommand(lampOffCommand);
        remote.buttonPressed(); // "Lamp is off" 출력
    }
}


위 예제에서는 RemoteControl 객체를 통해 Lamp 객체의 상태를 변경하는데, 이때 RemoteControl 객체는 Command 객체를 가지고 있으며, Command 객체를 호출하여 Lamp 객체의 상태를 변경합니다. 이를 통해 요청과 수신자를 분리하고, 유연한 코드를 작성할 수 있습니다.

반응형