커맨드 패턴(Command Pattern)은 행동 패턴 중 하나로
행동 패턴은 주로 객체 간의 상호작용에 초점을 맞춥니다. 이러한 상호작용은 객체들이 서로 메시지를 전송하고 그에 따라 동작을 변경하거나 실행하는 방식을 나타냅니다. 행동 패턴은 이러한 객체 간의 상호작용을 효율적으로 설계하기 위한 다양한 전략과 구조를 제공합니다.
커맨드 패턴이란?
요청 자체를 객체화 하는 것을 목표로 합니다. 이 패턴은 요청이 서로 다른 사용자, 시간 또는 프로젝트에 따라 달라질 수 있을 때 유용합니다. 이러한 요청을 객체로 만들면, 요청을 큐에 저장하거나 로그로 기록하고 재실행할 수 있습니다.
어떤 객체(A)에서 다른 객체(B)의 메서드를 실행하려면 객체(B)를 참조하고 있어야 하는 의존성이 발생한다. 이와 같은 상황에서 커맨드패턴을 적용하면 의존성을 제거할 수 있다. 또한 기능이 수정되거나 변경이 일어날 때 A클래스의 코드를 수정없이 기능에 대한 클래스를 정의하면 되므로 시스템이 확장성이 있으면서 유연성을 가질 수 있다.
커맨드 패턴 구조

클래스 다이어그램과 위에서 예시로 들었던 에디터 객체들의 역할을 연결해보면 아래와 같습니다.
invoker1 = 1.Ctrl+C
invoker2 = 2.마우스 오른쪽 클릭하여 나타난 컨텍스트 메뉴에서 복사 메뉴 선택
invoker3 = 3.에디터 상단 메뉴의 편집->복사 메뉴 선택
선택된 문자열 정보를 알고 있는 에디터 객체, 명령에 의해 실제 작업을 수행하는 역할입니다(선택 문자열을 클립보드에 복사)
에디터 객체가 클립보드에 선택된 문자열 정보를 저장하라는 명령을 내릴 구체화된 커맨드 객체(직접 선택 문자열을 클립보드에 저장하지 않음-리시버에게 명령)
에디터, 복사명령, 인보커들의 객체 생성 및 의존성 설정을 하는 최상위 객체
요구사항에 따라 client 는 컴포지트 패턴을 활용하여 ConcreteCommand2 와 같이 다수의 명령 집합을 관리하는 객체를 활용함으로써 인보커가 한번에 여러 명령을 실행하게 할 수도 있습니다.(Meta Command Pattern , MacroCommand)
필요하다면 Command 인터페이스에 undo 추상메소드를 추가하고, 실행취소와 같은 기능을 편리하게 구현 할 수 있습니다.
커맨드 패턴 코드
먼저 인터페이스를 정의합니다.
public interface Command {
public void run();
}
Heater를 켜는 명령을 클래스화 하여, HeaterOnCommand 클래스를 정의하고, Heater 클래스는 그대로 히터를 켜는 powerOn() 메서드를 정의합니다.
public class HeaterOnCommand implements Command{
private Heater heater;
public HeaterOnCommand(Heater heater){
this.heater = heater;
}
public void run(){
heater.powerOn();
}
}
public class Heater {
public void powerOn(){
System.out.println("Heater on");
}
}
마찬가지로 Lamp를 켜는 명령을 클래스화 하여, LampOnCommand 클래스를 정의하고, Lamp 클래스는 그대로 램프를 켜는 turnOn() 메서드를 정의합니다.
public class LampOnCommand implements Command{
private Lamp lamp;
public LampOnCommand(Lamp lamp){
this.lamp = lamp;
}
public void run(){
lamp.turnOn();
}
}
public class Lamp {
public void turnOn(){
System.out.println("Lamp on");
}
}
OKGoogle 클래스의 talk() 메서드에서는 Command 인터페이스의 run() 메서드를 하여 명령을 실행합니다.
public class OKGoogle {
private Command command;
public void setCommand(Command command){
this.command = command;
}
public void talk(){
command.run();
}
}
OKGoogle을 사용하는 Client 클래스를 정의합니다.
public class Client {
public static void main(String args[]){
Heater heater = new Heater();
Lamp lamp = new Lamp();
Command heaterOnCommand = new HeaterOnCommand(heater);
Command lampOnCommand = new LampOnCommand(lamp);
OKGoogle okGoogle = new OKGoogle();
// 히터를 켠다
okGoogle.setCommand(heaterOnCommand);
okGoogle.talk();
// 램프를 켠다
okGoogle.setCommand(lampOnCommand);
okGoogle.talk();
}
}
🙈[디자인패턴] 커맨드 패턴 ( Command Pattern )🐵
[디자인 패턴] 커맨드 패턴(Command Pattern)