본문 바로가기
프로그래밍/Java

디자인패턴 - Command 패턴

by freeelifee 2025. 4. 10.
728x90

Command 패턴은 행동(명령)을 객체로 캡슐화하여, 요청 내역을 매개변수화하거나 큐에 저장하거나 실행 취소(undo) 기능을 지원할 수 있도록 설계된 행위 디자인 패턴(Behavioral Pattern)입니다. 이 패턴은 요청, 작업, 명령 등을 객체로 만들어서 다양한 요구사항에 따라 실행하거나 조합할 수 있게 도와줍니다.


### 핵심 개념
1. 명령 캡슐화:
   - Command 패턴은 실행하고자 하는 명령을 단일 객체로 캡슐화합니다.
   - 이는 실행 대상(Receiver)과 실행 요청자(Invoker)를 분리하여 서로 간의 의존성을 줄입니다.

2. 실행 취소/재실행(Undo/Redo):
   - 명령을 객체로 캡슐화하면 실행 내역을 저장할 수 있어, 이를 통해 undo/redo 기능을 쉽게 구현할 수 있습니다.

3. 확장성:
   - 새로운 명령을 추가할 때 기존 코드를 수정하지 않고도 유연하게 확장할 수 있습니다.


### 구조
Command 패턴은 다음과 같은 주요 구성 요소를 포함합니다:

1. Command 인터페이스  
   - 실행할 동작을 정의하는 인터페이스.
   - 메서드 예: `execute()` 및 `undo()`

2. ConcreteCommand 클래스  
   - Command 인터페이스를 구현하고, 실제 동작을 실행할 로직을 포함.

3. Receiver (수신자)  
   - 명령이 실행될 실제 대상. 명령 객체가 Receiver의 메서드를 호출.

4. Invoker (요청자)  
   - 명령 객체를 호출하여 작업을 실행. 명령 객체의 참조를 저장.

5. Client (클라이언트)  
   - ConcreteCommand와 Receiver를 생성하고 설정하는 역할.


### Command 패턴 구현 예제

#### 1. Command 인터페이스

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


#### 2. Receiver (수신자)

// TV 수신자
public class Television {
    public void turnOn() {
        System.out.println("TV가 켜졌습니다.");
    }
    
    public void turnOff() {
        System.out.println("TV가 꺼졌습니다.");
    }
}


#### 3. ConcreteCommand 구현

// TV 켜기 명령
public class TurnOnCommand implements Command {
    private Television tv;

    public TurnOnCommand(Television tv) {
        this.tv = tv;
    }

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

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

// TV 끄기 명령
public class TurnOffCommand implements Command {
    private Television tv;

    public TurnOffCommand(Television tv) {
        this.tv = tv;
    }

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

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


#### 4. Invoker (요청자)

// 리모컨 (요청자)
public class RemoteControl {
    private Command command;

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

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

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



#### 5. Client (클라이언트)

public class CommandPatternExample {
    public static void main(String[] args) {
        // Receiver 생성
        Television tv = new Television();

        // ConcreteCommand 생성
        Command turnOn = new TurnOnCommand(tv);
        Command turnOff = new TurnOffCommand(tv);

        // Invoker 설정
        RemoteControl remote = new RemoteControl();

        // TV 켜기
        remote.setCommand(turnOn);
        remote.pressButton(); // 출력: TV가 켜졌습니다.

        // Undo (TV 끄기)
        remote.pressUndo(); // 출력: TV가 꺼졌습니다.

        // TV 끄기
        remote.setCommand(turnOff);
        remote.pressButton(); // 출력: TV가 꺼졌습니다.

        // Undo (TV 켜기)
        remote.pressUndo(); // 출력: TV가 켜졌습니다.
    }
}

### Command 패턴의 장점
1. 명령을 캡슐화:
   - 명령을 객체로 다룸으로써, 코드의 구조화 및 조합이 용이.
2. 확장성 증가:
   - 새로운 명령 추가 시 기존 코드에 영향을 주지 않음.
3. 실행 취소(Undo) 및 기록(Log):
   - 실행 내역을 저장하여 undo/redo 기능 구현 가능.
4. 요청자와 실행 대상의 분리:
   - 요청자(Invoker)와 Receiver 간의 결합도를 낮춰 유연성을 높임.

 

### Command 패턴의 단점
1. 복잡성 증가:
   - 간단한 작업에도 여러 클래스(Command, ConcreteCommand 등)를 생성해야 함.
2. 오버헤드:
   - 명령을 캡슐화하는 추가 작업이 필요한 경우.


### Command 패턴의 활용 사례
1. GUI 버튼:
   - 버튼 클릭 시 다양한 행동(명령)을 실행.
2. 게임 명령:
   - 캐릭터 이동, 공격 등을 캡슐화.
3. 홈 오토메이션 시스템:
   - 집 안의 장치를 명령 단위로 캡슐화.
4. Undo/Redo 기능:
   - 텍스트 에디터, 그래픽 프로그램 등에서 실행 취소.

728x90

'프로그래밍 > Java' 카테고리의 다른 글

람다 표준 함수적 인터페이스  (0) 2025.04.10
디자인패턴 - Strategy 패턴  (0) 2025.04.10
디자인패턴  (0) 2025.04.09
Optional  (0) 2025.04.08
Enum  (0) 2025.04.08