SW공학/디자인패턴
[SW공학 | 디자인패턴] 11. 커맨드 패턴 (Command Pattern)
revolutionarylife
2024. 11. 12. 09:00
반응형
🕹️ [SW공학 | 디자인패턴] 11. 커맨드 패턴 (Command Pattern)
목차
- 커맨드 패턴 개요
- 커맨드 패턴의 필요성
- 커맨드 패턴의 구조
- 커맨드 패턴 예제
- 커맨드 패턴의 장점과 단점
- 마무리
커맨드 패턴 개요
안녕하세요! 오늘은 작업을 객체로 캡슐화하여 요청과 수행을 분리하는 커맨드 패턴(Command Pattern)에 대해 알아보겠습니다. 커맨드 패턴은 행동 패턴(Behavioral Pattern) 중 하나로, 요청을 커맨드 객체로 캡슐화하여 여러 작업을 구성할 수 있게 합니다.
이 패턴을 사용하면 작업 요청과 실행을 분리하여 명령을 취소하거나 되돌리는 기능을 쉽게 구현할 수 있습니다.
커맨드 패턴의 필요성
UI에서 버튼 클릭, 키보드 입력, 메뉴 선택과 같은 작업을 처리할 때, 명령을 독립적으로 관리하고 실행 기록을 남기려면 코드가 복잡해질 수 있습니다. 커맨드 패턴을 사용하면 각 명령을 객체로 분리하여, 작업을 쉽게 관리하고 추적할 수 있습니다.
커맨드 패턴의 구조
커맨드 패턴은 Command (명령 인터페이스), ConcreteCommand (구체적인 명령), Receiver (수행자), Invoker (명령 호출자)로 구성됩니다.
- Command (명령 인터페이스)
- 명령 실행 메서드인 execute()를 정의하여, 구체적인 명령들이 동일한 인터페이스를 통해 실행됩니다.
- ConcreteCommand (구체적인 명령)
- Command 인터페이스를 구현하여 구체적인 명령을 정의하고, 해당 명령을 수행할 Receiver 객체를 보유합니다.
- Receiver (수행자)
- ConcreteCommand가 호출할 실제 작업을 수행하는 객체로, 명령의 구체적인 동작을 실행합니다.
- Invoker (명령 호출자)
- 명령 객체를 저장하고 실행하며, 보통 UI의 버튼이나 입력 장치와 같은 역할을 합니다.
커맨드 패턴 예제
아래 예제는 리모컨을 사용하여 전등을 켜고 끄는 작업을 커맨드 패턴으로 구현한 것입니다.
// Command 인터페이스
interface Command {
void execute();
}
// ConcreteCommand: 전등을 켜는 명령
class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
}
// ConcreteCommand: 전등을 끄는 명령
class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOff();
}
}
// Receiver: 전등 클래스
class Light {
public void turnOn() {
System.out.println("전등이 켜졌습니다.");
}
public void turnOff() {
System.out.println("전등이 꺼졌습니다.");
}
}
// Invoker: 리모컨 클래스
class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
// 클라이언트 코드
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(); // 출력: 전등이 켜졌습니다.
remote.setCommand(lightOff);
remote.pressButton(); // 출력: 전등이 꺼졌습니다.
}
}
출력 결과:
전등이 켜졌습니다.
전등이 꺼졌습니다.
예제 설명
- Command 인터페이스: execute() 메서드를 정의하여 모든 명령이 동일한 방식으로 호출됩니다.
- LightOnCommand, LightOffCommand (ConcreteCommand): 각 명령 클래스는 Command 인터페이스를 구현하여 전등을 켜고 끄는 동작을 수행합니다.
- Light (Receiver): 실제 작업을 수행하는 전등 클래스입니다. turnOn()과 turnOff() 메서드로 전등의 상태를 변경합니다.
- RemoteControl (Invoker): 명령을 설정하고 실행하는 리모컨 클래스입니다. setCommand()로 명령을 설정하고, pressButton()으로 명령을 실행합니다.
커맨드 패턴의 장점과 단점
장점
- 유연성 증가: 다양한 명령을 독립적으로 관리할 수 있어, 명령을 추가하거나 수정하기 쉽습니다.
- 작업 기록 및 취소 기능: 명령을 객체로 분리하여 작업 기록 및 되돌리기 기능을 구현할 수 있습니다.
- 결합도 감소: Invoker와 Receiver가 직접적으로 결합되지 않고 Command 인터페이스로 상호작용하여 결합도를 낮춥니다.
단점
- 복잡성 증가: 각 명령마다 클래스를 생성해야 하므로, 명령의 수가 많아질수록 코드가 복잡해질 수 있습니다.
- 메모리 사용 증가: 모든 명령을 객체로 생성하므로, 명령 객체가 많아지면 메모리 사용이 증가할 수 있습니다.
마무리
커맨드 패턴은 작업을 명령 객체로 캡슐화하여 유연하게 작업을 추가, 수정, 취소할 수 있는 설계 패턴입니다. 이를 통해 명령을 손쉽게 관리하고 작업을 확장할 수 있습니다. 커맨드 패턴을 활용하여 작업을 효율적으로 처리하고 유지보수성을 높여보세요! 🕹️
반응형