반응형
🎈 메멘토 패턴 (Memento Pattern)
• 객체 상태를 저장/복원하는 디자인 패턴
• 스냅샷과 같은 기능으로 "실행 취소" 및 "다시 실행" 구현에 유용
• 활용 예시: 텍스트 에디터, 게임 상태, 회원가입 양식, 데이터베이스 백업 등
• 디자인 패턴 중 행위 패턴에 해당된다.
[예제코드]
#include <iostream>
#include <string>
class Character {
private:
std::string name;
int health;
public:
Character(std::string name, int health) : name(name), health(health) {}
void SetState(std::string name, int health) {
this->name = name;
this->health = health;
}
void ShowState() {
std::cout << "이름: " << name << ", 체력: " << health << std::endl;
}
class Memento {
private:
std::string name;
int health;
public:
Memento(std::string name, int health) : name(name), health(health) {}
std::string GetName() {
return name;
}
int GetHealth() {
return health;
}
};
Memento CreateMemento() {
return Memento(name, health);
}
void RestoreFromMemento(Memento memento) {
this->name = memento.GetName();
this->health = memento.GetHealth();
}
};
class Caretaker {
private:
Character::Memento memento;
public:
Caretaker() : memento("Default", 0) {}
void SetMemento(Character::Memento memento) {
this->memento = memento;
}
Character::Memento GetMemento() {
return memento;
}
};
int main() {
Character character("까망", 100);
Caretaker caretaker;
// 상태 저장
caretaker.SetMemento(character.CreateMemento());
character.ShowState();
// 상태 변경
character.SetState("하르방", 50);
character.ShowState();
// 상태 복원
character.RestoreFromMemento(caretaker.GetMemento());
character.ShowState();
return 0;
}
Character 클래스는 Memento 내부 클래스로 상태를 저장/복원한다.
Caretaker 클래스는 Memento를 보관하고 복원을 요청한다.
🎈 메멘토 패턴 장단점
+ 상태 저장과 복원 분리:
객체 내부 상태를 외부에서 접근하지 않고도 복원하기에
객체 캡슐화와 데이터 은닉을 유지할 수 있다.
+ 상태 이력 관리: 객체의 상태를 여러 시점에서 저장하고 관리할 수 있다.
→ "실행 취소"와 "다시 실행"과 같은 기능 구현에 유용
+ 새로운 기능 추가와 변경시 안정성 확보
- 메모리 사용량 증가: 객체 상태 저장을 위한 추가 메모리 필요
- 복잡성 증가: 객체 상태 저장/복원 로직이 추가되므로 유지보수와 이해도가 어려워질 수 있다.
[예제코드]
#include <iostream>
#include <string>
#include <vector>
class TextEditor {
private:
std::string text;
public:
TextEditor() : text("") {}
void SetText(const std::string& newText) {
text = newText;
}
std::string GetText() const {
return text;
}
class Memento {
private:
std::string savedText;
public:
Memento(const std::string& text) : savedText(text) {}
std::string GetSavedText() const {
return savedText;
}
};
Memento CreateMemento() {
return Memento(text);
}
void RestoreFromMemento(const Memento& memento) {
text = memento.GetSavedText();
}
};
class Caretaker {
private:
std::vector<TextEditor::Memento> savedStates;
public:
void AddMemento(const TextEditor::Memento& memento) {
savedStates.push_back(memento);
}
TextEditor::Memento GetMemento(int index) {
if (index >= 0 && index < savedStates.size()) {
return savedStates[index];
}
// [에러 처리] 유효하지 않은 인덱스
return TextEditor::Memento("");
}
};
int main() {
TextEditor editor;
Caretaker caretaker;
// 텍스트 편집 및 상태 저장
editor.SetText("까망 하르방");
caretaker.AddMemento(editor.CreateMemento());
editor.SetText("까망 포레스트");
caretaker.AddMemento(editor.CreateMemento());
editor.SetText("@gm.snack");
caretaker.AddMemento(editor.CreateMemento());
// 현재 상태 출력
std::cout << "현재: " << editor.GetText() << std::endl;
// 이전 상태로 복원
int restoreIdx = 0;
editor.RestoreFromMemento(caretaker.GetMemento(restoreIdx));
std::cout << "[" << restoreIdx << "] 상태로 변경: " << editor.GetText() << std::endl;
restoreIdx = 1;
editor.RestoreFromMemento(caretaker.GetMemento(restoreIdx));
std::cout << "[" << restoreIdx << "] 상태로 변경: " << editor.GetText() << std::endl;
return 0;
}
객체 상태를 caretake 객체에 저장하여
원하는 시점의 상태로 복원할 수 있다.
반응형
'까망 동네 > 디자인 패턴' 카테고리의 다른 글
[디자인 패턴] 경량 패턴 (Flyweight Pattern) (2) | 2023.11.12 |
---|---|
[디자인 패턴] 프록시 패턴 (Proxy Pattern) (3) | 2023.11.11 |
[디자인패턴] 퍼사드 패턴 (Facade Pattern) (54) | 2023.11.09 |
[디자인 패턴] 관찰자(Observer) 패턴 (4) | 2023.11.06 |
[디자인패턴] 컴포지트 패턴 (Composite Pattern) (1) | 2023.11.05 |
댓글