커맨드 패턴(Command Pattern)
요청 내역을 객체로 캡슐화해서 객체를 서로 다른 요청 내역에 따라 매개변수화할 수 있습니다. 이러면 요청을 큐에 저장하거나 로그로 기록하거나 작업 취소 기능을 사용할 수 있습니다.
구성 요소
- 커맨드 인터페이스 (Command Interface): 모든 커맨드 객체가 구현해야 하는 인터페이스로, 일반적으로
execute()
메서드를 포함합니다. - 구체적인 커맨드 클래스 (Concrete Command Class): 특정 작업을 수행하는 커맨드 클래스입니다. 이 클래스는 작업을 수행할 리시버 객체를 참조하고 있으며,
execute()
메서드에서 리시버 객체의 메서드를 호출합니다. - 리시버 (Receiver): 실제로 작업을 수행하는 클래스입니다. 커맨드 객체는 이 리시버 객체의 메서드를 호출하여 작업을 수행합니다.
- 인보커 (Invoker): 커맨드 객체를 실행하는 주체입니다. 보통 여러 커맨드 객체를 저장하고 필요할 때
execute()
메서드를 호출합니다. - 클라이언트 (Client): 인보커와 커맨드 객체들을 설정하는 역할을 합니다.
코드
Command Interface:
public interface Command {
void execute();
}
Concrete Command:
public class LightOnCommand implements Command {
Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.on();
}
}
Receiver:
public class Light {
public void on() {
System.out.println("Light is on");
}
public void off() {
System.out.println("Light is off");
}
}
Invoker:
public class RemoteControl {
Command slot;
public RemoteControl() {}
public void setCommand(Command command) {
slot = command;
}
public void pressButton() {
slot.execute();
}
}
Client:
public class RemoteLoader {
public static void main(String[] args) {
RemoteControl remote = new RemoteControl();
Light livingRoomLight = new Light();
LightOnCommand lightOn = new LightOnCommand(livingRoomLight);
remote.setCommand(lightOn);
remote.pressButton();
}
}
장단점
장점:
- 요청을 캡슐화하여 클라이언트와 리시버 간의 결합도를 낮춥니다.
- 요청을 저장, 로깅, 취소할 수 있습니다.
- 새로운 커맨드를 쉽게 추가할 수 있습니다.
단점:
- 클래스의 수가 증가하여 시스템이 복잡해질 수 있습니다.
- 커맨드 객체를 생성 및 관리하는 데에 비용이 추가됩니다.
예제 시나리오:
- 리모컨 시스템에서 버튼 하나를 눌러 여러 가전제품을 제어하는 시나리오
- 게임에서 매크로를 저장하고 실행하는 시나리오
- 작업을 큐에 넣어 순차적으로 실행하거나, 작업을 로그로 남겨서 추적하는 시스템
실제 활용 사례:
- GUI 애플리케이션에서 메뉴 항목 선택, 버튼 클릭과 같은 사용자 동작을 커맨드 패턴으로 처리
- 트랜잭션 시스템에서 작업을 캡슐화하여 취소 기능 구현
핵심 정리
- 커맨드 패턴을 사용하면 요청하는 객체와 요청을 수행하는 객체를 분리할 수 있습니다.
- 이렇게 분리하는 과정의 중심에는 커맨드 객체가 있으며, 이 객체가 행동이 들어있는 리시버를 캡슐화합니다.
- 인보커는 무언가 요청할 때 커맨드 객체의
excute()
메소드를 호출하면 됩니다.excute()
메소드는 리시버에 있는 행동을 호출합니다. - 커맨드는 인보커를 매개변수화 할 수 있습니다. 실행 중에 동적으로 매개변수화를 설정할 수도 있습니다.
excute()
메소드가 마지막으로 호출되기 전의 상태로 되돌리는 작업취소 메소드를 구현하면 커맨드 패턴으로 작업 취소 기능을 구현할 수도 있습니다.- 매크로 커맨드는 커맨드를 호가장해서 여러 개의 커맨드를 한 번에 호출할 수 있게 해 주는 가장 간편한 방법입니다. 매크로 커맨드로도 어렵지 않게 작업 취소 기능을 구현할 수 있습니다.
- 프로그래밍을 하다 보면 요청을 스스로 처리하는 '스마트' 커맨드 객체를 사용하는 경우도 종종 있습니다.
- 커맨드 패턴을 활용해서 로그 및 트랙재션 시스템을 구현할 수 있습니다.
'TIL' 카테고리의 다른 글
헤드 퍼스트 디자인 패턴 | 07장 적응시키기 (퍼사드 패턴) (0) | 2024.07.18 |
---|---|
헤드 퍼스트 디자인 패턴 | 07장 적응시키기 (어댑터 패턴) (0) | 2024.07.17 |
헤드 퍼스트 디자인 패턴 | 05장 하나뿐인 특별한 객체 만들기 (싱글턴 패턴) (0) | 2024.07.04 |
윷놀이에서 개가 나올 확률은 얼마나 될까? (0) | 2024.06.27 |
소프트웨어 설계를 위한 추상적, 구조적 사고 - 이선협 (0) | 2024.06.27 |