**커맨드 패턴**(Command pattern)이란 요청을 객체의 형태로 캡슐화하여 사용자가 보낸 요청을 나중에 이용할 수 있도록 매서드 이름, 매개변수 등 요청에 필요한 정보를 저장 또는 로깅, 취소할 수 있게 하는 패턴이다.

커맨드 패턴에는 명령(command), 수신자(receiver), 발동자(invoker), 클라이언트(client)의 네개의 용어가 항상 따른다. 커맨드 객체는 수신자 객체를 가지고 있으며, 수신자의 메서드를 호출하고, 이에 수신자는 자신에게 정의된 메서드를 수행한다. 커맨드 객체는 별도로 발동자 객체에 전달되어 명령을 발동하게 한다. 발동자 객체는 필요에 따라 명령 발동에 대한 기록을 남길 수 있다. 한 발동자 객체에 다수의 커맨드 객체가 전달될 수 있다. 클라이언트 객체는 발동자 객체와 하나 이상의 커맨드 객체를 보유한다. 클라이언트 객체는 어느 시점에서 어떤 명령을 수행할지를 결정한다. 명령을 수행하려면, 클라이언트 객체는 발동자 객체로 커맨드 객체를 전달한다.

구조
--

예
-

### C++

```
#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Command{
 public:
 virtual void execute(void) =0;
 virtual ~Command(void){};
};

class Ingredient : public Command {
 public:
 Ingredient(string amount, string ingredient){
 \_ingredient = ingredient;
 \_amount = amount;
 }
 void execute(void){
 cout << "\*Add "<< \_amount << "of "<< \_ingredient << endl;
 }
 private:
 string \_ingredient;
 string \_amount;
};

class Step : public Command {
 public:
 Step(string action, string time){
 \_action= action;
 \_time= time;
 }
 void execute(void){
 cout << "\*" << \_action << "for "<< \_time << endl;
 }
 private:
 string \_time;
 string \_action;
};

class CmdStack{
 public:
 void add(Command \*c) {
 commands.push\_back(c);
 }
 void createRecipe(void){
 for(vector<Command\*>::size\_type x=0;x<commands.size();x++){
 commands[x]->execute();
 }
 }
 void undo(void){
 if(commands.size() >= 1) {
 commands.pop\_back();
 }
 else {
 cout << "Can't undo" << endl;
 }
 }
 private:
 vector<Command\*> commands;
};

int main(void) {
 CmdStack list;

 //Create ingredients
 Ingredient first("2 tablespoons", "vegetable oil");
 Ingredient second("3 cups", "rice");
 Ingredient third("1 bottle","Ketchup");
 Ingredient fourth("4 ounces", "peas");
 Ingredient fifth("1 teaspoon", "soy sauce");

 //Create Step
 Step step("Stir-fry","3-4 minutes");

 //Create Recipe
 cout << "Recipe for simple Fried Rice" << endl;
 list.add(&first);
 list.add(&second);
 list.add(&step);
 list.add(&third);
 list.undo();
 list.add(&fourth);
 list.add(&fifth);
 list.createRecipe();
 cout << "Enjoy!" << endl;
 return 0;
}

```

### 자바

```
/\*the Invoker class\*/
public class Switch {
 private Command flipUpCommand;
 private Command flipDownCommand;

 public Switch(Command flipUpCmd,Command flipDownCmd){
 this.flipUpCommand=flipUpCmd;
 this.flipDownCommand=flipDownCmd;
 }

 public void flipUp(){
 flipUpCommand.execute();
 }

 public void flipDown(){
 flipDownCommand.execute();
 }
}

/\*Receiver class\*/

public class Light{
 public Light(){ }

 public void turnOn(){
 System.out.println("The light is on");
 }

 public void turnOff(){
 System.out.println("The light is off");
 }
}

/\*the Command interface\*/

public interface Command{
 void execute();
}

/\*the Command for turning on the light\*/

public class TurnOnLightCommand implements Command{
 private Light theLight;

 public TurnOnLightCommand(Light light){
 this.theLight=light;
 }

 public void execute(){
 theLight.turnOn();
 }
}

/\*the Command for turning off the light\*/

public class TurnOffLightCommand implements Command{
 private Light theLight;

 public TurnOffLightCommand(Light light){
 this.theLight=light;
 }

 public void execute(){
 theLight.turnOff();
 }
}

/\*The test class\*/
public class TestCommand{
 public static void main(String[] args){
 Light light=new Light();
 Command switchUp=new TurnOnLightCommand(light);
 Command switchDown=new TurnOffLightCommand(light);

 Switch s=new Switch(switchUp,switchDown);

 s.flipUp();
 s.flipDown();
 }
}

```

### 파이썬

```
class Switch(object):
 """The INVOKER class"""
    def \_\_init\_\_(self, flip\_up\_cmd, flip\_down\_cmd):
        self.flip\_up = flip\_up\_cmd
        self.flip\_down = flip\_down\_cmd

class Light(object):
 """The RECEIVER class"""
    def turn\_on(self):
        print("The light is on")
    def turn\_off(self):
        print("The light is off")

class LightSwitch(object):
 """The CLIENT class"""
    def \_\_init\_\_(self):
        lamp = Light()
        self.\_switch = Switch(lamp.turn\_on, lamp.turn\_off)

    def switch(self, cmd):
        cmd = cmd.strip().upper()
        if cmd == "ON":
            self.\_switch.flip\_up()
        elif cmd == "OFF":
            self.\_switch.flip\_down()
        else:
            print("Argument 'ON' or 'OFF' is required.")

# 파일이 모듈로 로딩되지 않고 스크립트로 실행될 때만 아래를 수행
if \_\_name\_\_ == "\_\_main\_\_":
    light\_switch = LightSwitch()
    print("Switch ON test.")
    light\_switch.switch("ON")
    print("Switch OFF test.")
    light\_switch.switch("OFF")
    print("Invalid Command test.")
    light\_switch.switch("\*\*\*\*")

```

| * v
* t
* e
소프트웨어 디자인 패턴 |
| --- |
| 4인방(Gang of four) 패턴 | 

|  |  |
| --- | --- |
| 생성 패턴 | 
* 추상 팩토리
* 빌더
* 팩토리 메소드
* 프로토타입
* 싱글턴

 |
| 구조 패턴 | 
* 어댑터
* 브리지
* 컴포지트
* 데코레이터
* 퍼사드
* 플라이웨이트
* 프록시

 |
| 동작 패턴 | 
* 책임 연쇄
* 커맨드
* 인터프리터
* 반복자
* 중재자
* 메멘토
* 옵서버
* 상태
* 전략
* 템플릿 메소드
* 비지터

 |

 |
| 동시성 패턴 | 
* 액티브 오브젝트
* Balking
* 바인딩 속성
* 더블 체크 라킹
* 이벤트 기반 비동기
* 가디드 서스펜션
* 조인
* 락
* 모니터 (동기화)
* 프로액터
* 반응자 패턴
* 읽기 쓰기 락
* 스케줄링 (컴퓨팅)
* 스레드 풀
* 스레드 로컬 스토리지

 |
| 아키텍처 패턴 | 
* 프론트 컨트롤러
* 인터셉터
* 모델-뷰-컨트롤러
* 모델-뷰-프리젠터
* 모델-뷰-뷰모델
* 다층 구조
* 사양
* 발행-구독 모델
* 네이키드 오브젝트
* 서비스 로케이터
* 액티브 레코드
* 아이덴티티 맵
* 데이터 접근 객체
* 데이터 전송 객체
* ADR
* 제어 반전

 |
| 기타 패턴 | 
* 블랙보드
* 비즈니스 델리게이트
* 컴포지트 엔티티
* 의존성 주입
* 인터셉터 필터
* 지연된 로딩
* 모의 객체
* 널 객체
* 객체 풀
* 서번트
* 트윈
* 타입 터널
* 메서드 체이닝

 |
| 관련 도서 | 
* 《디자인 패턴》
* 《Enterprise Integration Patterns》

 |
| 인물 | 
* 크리스토퍼 알렉산더
* 에릭 감마
* 랄프 존슨
* John Vlissides
* 그래디 부치
* 켄트 벡
* 워드 커닝햄
* 마틴 파울러
* 로버트 마틴
* Jim Coplien
* 더글라스 슈미트
* 린다 라이징

 |
| 커뮤니티 | 
* 힐사이드 그룹
* 포틀랜드 패턴 리포지토리

 |