JAVA/JAVA Design Pattern

JAVA 커맨드 패턴(Command Pattern)

임베디드 친구 2025. 1. 2. 15:56
반응형

커맨드 패턴은 요청을 객체로 캡슐화하여 실행, 취소, 재실행 등의 기능을 구조적으로 관리할 수 있도록 돕는 디자인 패턴입니다. 주로 명령 처리가 필요한 시스템에서 사용되며, 이벤트 처리나 작업 큐 관리에도 활용됩니다.

이번 포스팅에서는 커맨드 패턴의 개념, 동작 원리, 그리고 실생활 예제(버튼 클릭 이벤트)를 다뤄보겠습니다.


1. 커맨드 패턴이란?

커맨드 패턴은 명령을 객체로 캡슐화하는 방법을 제공합니다. 이렇게 하면 요청을 파라미터화하거나, 작업을 큐에 저장하거나, 실행 취소(Undo) 기능을 지원할 수 있습니다.

커맨드 패턴의 핵심 구성 요소:

  1. Command (명령 객체) : 실행될 작업에 대한 인터페이스를 정의합니다.
  2. ConcreteCommand (구체적인 명령) : Command 인터페이스를 구현하여 실제 작업을 실행합니다.
  3. Receiver (수신자) : 명령을 수행하는 주체입니다.
  4. Invoker (요청자) : 명령 객체를 실행하거나 취소합니다.
  5. Client (클라이언트) : 명령 객체를 생성하고 요청자에게 전달합니다.

2. 클래스 다이어그램

+------------------+          +------------------+
|     Command      |<---------|  ConcreteCommand |
|------------------|          |------------------|
| + execute()      |          | + execute()      |
| + undo()         |          | + undo()         |
+------------------+          +------------------+
         ^                            ^
         |                            |
+------------------+          +------------------+
|     Invoker      |          |     Receiver     |
|------------------|          |------------------|
| + setCommand()   |          | + action()       |
| + executeCommand()|         |                  |
+------------------+          +------------------+
         ^                            ^
         |                            |
+------------------+------------------+
|      Client      |
+------------------+

3. 커맨드 패턴 예제: 버튼 클릭 이벤트 처리

요구사항

  • 버튼 클릭 이벤트를 커맨드 패턴으로 처리합니다.
  • 실행과 취소(Undo) 기능을 구현합니다.

예제 코드

// Command 인터페이스
interface Command {
    void execute();
    void undo();
}

// Receiver: 명령을 실제 수행하는 객체
class Light {
    public void turnOn() {
        System.out.println("Light is ON");
    }

    public void turnOff() {
        System.out.println("Light is OFF");
    }
}

// ConcreteCommand: 구체적인 명령 클래스 (Light On)
class LightOnCommand implements Command {
    private Light light;

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

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

    @Override
    public void undo() {
        light.turnOff();
    }
}

// ConcreteCommand: 구체적인 명령 클래스 (Light Off)
class LightOffCommand implements Command {
    private Light light;

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

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

    @Override
    public void undo() {
        light.turnOn();
    }
}

// Invoker: 명령을 요청하는 객체 (버튼)
class RemoteControl {
    private Command command;

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

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

    public void pressUndo() {
        command.undo();
    }
}

// Client: 명령 객체를 생성하고 Invoker에게 전달
public class CommandPatternExample {
    public static void main(String[] args) {
        Light light = new Light();

        Command lightOn = new LightOnCommand(light);
        Command lightOff = new LightOffCommand(light);

        RemoteControl remote = new RemoteControl();

        // 전등 켜기
        remote.setCommand(lightOn);
        remote.pressButton(); // 출력: Light is ON
        remote.pressUndo();   // 출력: Light is OFF

        // 전등 끄기
        remote.setCommand(lightOff);
        remote.pressButton(); // 출력: Light is OFF
        remote.pressUndo();   // 출력: Light is ON
    }
}

4. 실행 결과

Light is ON
Light is OFF
Light is OFF
Light is ON

5. 커맨드 패턴의 장점

  1. 명령과 실행 주체의 분리: 요청을 처리하는 객체와 실제 명령을 수행하는 객체를 분리할 수 있습니다.
  2. 실행 취소(Undo) 기능: 명령을 되돌리는 기능을 쉽게 구현할 수 있습니다.
  3. 확장성: 새로운 명령이 추가될 때 기존 코드를 변경하지 않고 확장할 수 있습니다.
  4. 작업 큐 및 로그 관리: 명령 객체를 큐에 저장하거나 로그에 기록할 수 있어 작업 이력을 관리하기 쉽습니다.

6. 실제 사용 사례

  • GUI 버튼 클릭 이벤트 처리: 버튼 클릭 이벤트에 특정 명령 객체를 연결하여 실행합니다.
  • 작업 큐 시스템: 명령 객체를 큐에 저장하고 순차적으로 실행합니다.
  • Undo/Redo 기능: 텍스트 에디터, 그래픽 에디터 등에서 명령을 취소하거나 재실행합니다.

결론

커맨드 패턴은 요청을 객체로 캡슐화함으로써 명령 실행과 취소를 유연하게 관리할 수 있는 강력한 디자인 패턴입니다. GUI 이벤트 처리, 작업 큐 관리, Undo/Redo 기능 등 다양한 상황에서 활용할 수 있으니 실무에서도 잘 적용해보세요!

반응형