Thinking Different






Memento Pattern - 메멘토 패턴


  • 객체의 상태 정보를 저장 및 복원(Rollback)하는 패턴
  • 객체의 내부 상태정보만 가지는 클래스를 따로 생성하여 관리하는 구조로써, 저장할 상태정보가 많을 경우 문제가 될 수 있다
  • 대표적인 예로 바둑, 장기 등 기보 되돌리기, 바둑이 물리기 기능 등을 꼽을 수 있다.






샘플 코드)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <stack>
 
#if _UNICODE
typedef wstring tstring;
#else
typedef string tstring;
#endif
 
//------------------------------------------------------------------
// Memento 클래스
class Memento
{
public:
    Memento(tstring _state) { state = _state; }
 
public:
    tstring getState() const { return state; }
 
private:
    tstring state;
};
 
//------------------------------------------------------------------
// Originator 클래스
class Originator
{
public:
    void setState(tstring _state) 
    { 
        state = _state;
        wcout << _T("Originator: Setting state to ") << state << endl;
    }
 
public:
    void setMemento(Memento *m) 
    {
        if (m) 
        {
            state = m->getState(); 
            delete m; 
            wcout << _T("Originator: State after restoring from Memento ") << state << endl; 
        } 
    }
 
    Memento* createMemento() 
    {
        wcout << _T("Originator: Create to Memento ") << state << endl;
        return new Memento(state); 
    }
 
private:
    tstring state;
};
 
//------------------------------------------------------------------
// Caretaker 클래스 (Memento 관리)
class Caretaker
{
public:
    void pushMemento(Memento* m) { mStack.push(m); }
    Memento* popMemento() { Memento* m = mStack.top(); mStack.pop(); return m; }
 
private:
    stack<Memento*> mStack;
};
 
//------------------------------------------------------------------
// Main
int _tmain(int argc, _TCHAR* argv[])
{
    Caretaker mCaretaker;
    Originator *originator = new Originator();
 
    originator->setState(_T("state1"));
    mCaretaker.pushMemento(originator->createMemento());
 
    originator->setState(_T("state2"));
    mCaretaker.pushMemento(originator->createMemento());
    
    originator->setMemento(mCaretaker.popMemento());
    originator->setMemento(mCaretaker.popMemento());
 
    delete originator;
 
    return 0;
}





예제를 통한 메멘토 패턴(Memento Pattern) 알아보기



예제) 장기판 상태 정보를 메멘토로 저장하는 예제



사실 딱히 생각나는 예제가 없어서 간단히 문자열만 살짝 바꿔서 예제를 흉내내 봤습니다. 코드는 위에 샘플 코드랑 같습니다. 특별히 어려운 패턴이 아니니 '이렇게 사용한다' 라는 정도의 감만 잡으시면 될 것 같습니다.



예제 코드)


예제 코드는 위 샘플코드와 동일합니다. 따로 추가하지 않습니다.




예제 결과)