On this page
article
Misc: Command, State, Memento
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(); }
};