Design Pattern
07. Command Pattern
kangwook
2022. 8. 22. 21:11
클라이언트가 보낸 요청을 객체로 캡슐화하여 이를 나중에 이용할 수 있도록 관리하는 패턴
Command Pattern
Command Pattern은 요청을 객체로 캡슐화하여 사용자가 보낸 요청을 나중에 이용할 수 있도록 메서드 이름, 매개변수 등 요청에 필요한 정보를 저장 또는 취소할 수 있게하는 패턴이다.
- Invoker : 커맨드를 저장하는 객체
- Command : Receiver에게 동작을 수행하도록 요청하는 메서드를 가진 인터페이스
- ConcreteCommand : Command의 여러가지 동작들을 구체적으로 구현하는 클래스
- Receiver : 요구 사항을 수행하기 위해 어떤 일을 처리해야 하는지 알고 있는 객체
식당에서 발생하는 event로 이해하는 Command Pattern
- 고객이 웨이트리스에게 주문
- 웨이트리스는 주문서 작성 후 주방장에게 전달
- 주방장은 주문서를 토대로 요리
- 웨이트리스 입장
- 어떤 주문인지 조차도 몰라도 됨
- 누가 식사를 준비할지 몰라도 됨
- 주방장 입장
- 주문서를 읽고 필요한 메뉴만 준비하면 됨
- 누가 주문했는지 알 필요가 없음
식당 | 커맨드 패턴 |
손님 | Client |
웨이트리스 | Invoker 객체 |
손님에게 주문을 받는 행위 | setCommand() |
주문서 | Command 객체 |
주방장 | Receiver 객체 |
주문을 전달하여 요리를 요청하는 행위 | execute() |
Singleton Pattern 예제
Remote Control을 이용해 전등을 키는 것
- 리모컨의 명령을 실행시키는 커맨드를 저장할 SimpleRemoteControl
- 여러 가지 동작들에 대한 수행을 요청하는 Command와 구체적으로 구현하는 LightCommand
- 요구사항을 어떻게 수행하기 위해 일을 처리할 객체인 Light
- 싱글턴 패턴을 적용시킨 코드
- Command 클래스
- Command 클래스는 오로지 execute() 메서드만 제공
public interface Command {
void execute();
}
- ConcreteCommand: LightCommand 클래스
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.on();
}
}
- Receiver : Light 클래스
public class Light {
public void on() {
System.out.println("turn on light");
}
public void off() {
System.out.println("turn off light");
}
}
- Invoker를 이용해 Command 객체 사용 : SimpleRemoteControl 클래스
public class SimpleRemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void buttonWasPressed() {
command.execute();
}
}
- 이를 실행시킬 Client: RemoteControlTest 클래스
public class RemoteControlTest {
public static void main(String[] args) {
SimpleRemoteControl remote = new SimpleRemoteControl(); // Invoker
Light light = new Light(); // Receiver
LightOnCommand lightOn = new LightOnCommand(light); // Command
remote.setCommand(lightOn);
remote.buttonWasPressed();
}
}
- 출력 결과
Turn on light
결론
- 실행될 기능을 캡슐화함으로써 주어진 여러 기능을 실행할 수 있는 재사용성이 높은 클래스를 설계하는 행동 패턴(Behavioral Pattern)중 하나
- 장점
- 요청부와 동작부를 분리시켜주기 때문에 시스템의 결합도를 낮출 수 있음
→ 각 객체들이 수정되어도 다른 객체가 영향을 받지 않음 - Invoker와 Receiver간의 의존성을 제거
- 요청부와 동작부를 분리시켜주기 때문에 시스템의 결합도를 낮출 수 있음
- 단점
- Receiver 및 Receiver의 동작이 추가된다면 그 동작에 대한 클래스를 만들어야 하기 때문에 다소 복잡해질 수 있음
- 모든 작업이 독립적인 ConcreteCommand 클래스이므로 구현 및 유지 보수해야하는 클래스가 많음
본문은 Head First Design Pattern (2004) 를 참고하여 공부하고 작성하였음