Command

Command 패턴은 요청을 객체로 캡슐화해서 실행하거나 되돌릴 수 있도록 만드는 패턴이다.

  • 요청을 실행할 인터페이스 ICommand를 정의하고
  • 명령 객체들을 스택 등에 저장한 후 undo() 처리까지 가능하게 한다
  #include <iostream>
#include <stack>
#include <string>

// 명령 인터페이스
struct ICommand {
    virtual void execute() = 0;
    virtual void undo() = 0;
    virtual ~ICommand() {}
};

// 구체 명령
class InsertCommand : public ICommand {
    std::string& buffer;
    std::string text;
public:
    InsertCommand(std::string& buf, const std::string& txt) : buffer(buf), text(txt) {}
    void execute() override {
        buffer += text;
    }
    void undo() override {
        buffer.erase(buffer.size() - text.size());
    }
};

// 명령 관리자
class CommandManager {
    std::stack<ICommand*> undo_stack;
    std::stack<ICommand*> redo_stack;
public:
    void execute(ICommand* cmd) {
        cmd->execute();
        undo_stack.push(cmd);
        // 새로운 실행 시 redo는 초기화됨
        while (!redo_stack.empty()) redo_stack.pop();
    }

    void undo() {
        if (!undo_stack.empty()) {
            ICommand* cmd = undo_stack.top();
            undo_stack.pop();
            cmd->undo();
            redo_stack.push(cmd);
        }
    }

    void redo() {
        if (!redo_stack.empty()) {
            ICommand* cmd = redo_stack.top();
            redo_stack.pop();
            cmd->execute();
            undo_stack.push(cmd);
        }
    }

    ~CommandManager() {
        while (!undo_stack.empty()) { delete undo_stack.top(); undo_stack.pop(); }
        while (!redo_stack.empty()) { delete redo_stack.top(); redo_stack.pop(); }
    }
};

// 사용 예시
int main() {
    std::string buffer;
    CommandManager manager;

    manager.execute(new InsertCommand(buffer, "Hello "));
    manager.execute(new InsertCommand(buffer, "World!"));
    std::cout << buffer << std::endl; // Hello World!

    manager.undo();
    std::cout << buffer << std::endl; // Hello

    manager.redo();
    std::cout << buffer << std::endl; // Hello World!

    return 0;
}
  

State

State 패턴은 객체의 내부 상태에 따라 동작이 바뀌도록 설계하는 패턴이다. 상태를 클래스로 분리해서, 객체가 상태에 따라 위임하도록 구성한다.

  class Context;

class State {
public:
    virtual void handle(Context* c) = 0;
};

class StateA : public State {
public:
    void handle(Context* c) override {
        std::cout << "State A 행동" << std::endl;
        // 상태 전이 예시: c->setState(new StateB());
    }
};

class Context {
    State* state;
public:
    Context(State* s) : state(s) {}
    void request() { state->handle(this); }
    void setState(State* s) { state = s; }
};
  

Memento

Memento 패턴은 객체 내부 상태를 저장했다가 나중에 복원할 수 있게 만드는 패턴이다. 캡슐화를 깨뜨리지 않으면서도, 이전 상태로 되돌릴 수 있다.

  class State {
    int data;
public:
    State(int d) : data(d) {}
    int get() const { return data; }
};

class Originator {
    int data;
public:
    void set(int d) { data = d; }
    State save() { return State(data); }
    void load(const State& s) { data = s.get(); }
};