본문 바로가기
CS(Computer Science)지식/[C++] 디자인 패턴

명령 패턴(Command Pattern) 이해하기 : 쉽게 설명한 디자인 패턴(C++)

by 엔지니어 청년 2024. 1. 29.

명령 패턴(Command Pattern)이란?


명령 패턴은 행동 디자인 패턴 중 하나로, 요청을 객체의 형태로 캡슐화하여 서로 다른 사용자의 매개 변수를 캡슐화합니다. 이 패턴은 요청 자체를 객체로 만들어서 이를 클라이언트에게 전달하는 방식을 사용합니다. 이렇게 하면 클라이언트는 요청이 서비스를 어떻게 수행하는지 알 필요 없이 서비스를 사용할 수 있습니다.

명령 패턴은 다음과 같은 경우에 유용합니다:

  • 요청을 큐에 넣고 나중에 실행하려는 경우
  • 요청을 로그에 기록하고 시스템 충돌 후에 요청을 재실행하려는 경우
  • 구조화된 요청을 발행하는 것이 필요한 경우, 즉 요청을 발행하는 객체와 요청을 수행하는 객체를 분리하려는 경우

예시 코드


다음은 C++로 작성된 간단한 명령 패턴의 예입니다:

#include <iostream>
#include <memory>
#include <vector>

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

// Concrete Command
class HelloCommand : public Command {
public:
    void execute() const override {
        std::cout << "Hello Command Pattern!" << std::endl;
    }
};

// Invoker
class Invoker {
public:
    void addCommand(std::unique_ptr<Command> command) {
        commands.push_back(std::move(command));
    }

    void executeCommands() {
        for (const auto& command : commands) {
            command->execute();
        }
    }

private:
    std::vector<std::unique_ptr<Command>> commands;
};

int main() {
    Invoker invoker;
    invoker.addCommand(std::make_unique<HelloCommand>());
    invoker.executeCommands();  // Output: Hello Command Pattern!

    return 0;
}

위 코드에서 Command는 모든 명령이 구현해야 하는 인터페이스입니다. HelloCommandCommand 인터페이스를 구현하는 구체적인 명령입니다. Invoker는 명령을 큐에 추가하고, 큐에 있는 모든 명령을 실행하는 클래스입니다.

클래스 다이어그램


    +-----------------+
    |     Command     |
    +-----------------+
    | virtual ~Command|
    | virtual execute |
    +-----------------+
            ^
            |
    +-----------------+
    |  HelloCommand   |
    +-----------------+
    | execute         |
    +-----------------+
            ^
            |
    +-----------------+
    |     Invoker     |
    +-----------------+
    | addCommand      |
    | executeCommands |
    +-----------------+

이 패턴을 사용하면 요청을 발행하는 객체와 요청을 수행하는 객체를 분리할 수 있으므로, 시스템의 결합도를 낮추고 유지 보수성을 향상시킬 수 있습니다. 또한 명령 패턴은 명령의 실행을 연기하거나, 명령을 큐에 넣고, 명령의 실행을 취소하거나 재실행하는 등의 기능을 쉽게 구현할 수 있습니다.