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 기능:
- 텍스트 에디터, 그래픽 프로그램 등에서 실행 취소.
'프로그래밍 > Java' 카테고리의 다른 글
람다 표준 함수적 인터페이스 (0) | 2025.04.10 |
---|---|
디자인패턴 - Strategy 패턴 (0) | 2025.04.10 |
디자인패턴 (0) | 2025.04.09 |
Optional (0) | 2025.04.08 |
Enum (0) | 2025.04.08 |