Design Patterns/Behavioral Patterns

Memento Pattern (C++)

개발새발 2019. 12. 30. 23:07
반응형

Memento Pattern (메멘토 패턴)

목적

캡슐화를 위배하지 않은 채 객체의 내부 상태를 저장하고 되돌아올 수 있도록 한다.

 

사용 시나리오

  • 텍스트 에디터를 개발중에 있다고 가정하자
  • 텍스트 에디터에 ctrl Z입력시 이전에 입력했던 텍스트로 상태를 불러오는 기능을 추가한다.

 

[Memento]

class InputMemento {
public:
    InputMemento(string& input) {
        this->input = input;
    }
    string getState() {
        return this->input;
    }
private:
    string input;
};

[Originator]

class InputOriginator {
public:
    void setCurrentInput(string input) {
        this->currentInput = input;
    }
    InputMemento* saveCurrentInputToMemento() {
        cout<<"Save Current Input to Memento :"<<currentInput<<endl;
        return new InputMemento(currentInput);
    }
    void restoreFromInputMemento(InputMemento* inputMemento) {
        this->currentInput = inputMemento->getState();
        delete inputMemento;
    }
    string getCurrentInput() {
        return currentInput;
    }
    
private:
    string currentInput;
};

[CareTaker]

class InputCareTaker {
public:
    void saveMemento(InputMemento* inputMemento) {
        inputMementos.push(inputMemento->getState());
    }
    InputMemento* popSavedMemento() {
        InputMemento* ret = new InputMemento(inputMementos.top());
        inputMementos.pop();
        return ret;
    }
private:
    stack<string> inputMementos;
};

[Client]

int main(int argc, const char * argv[]) {
    InputCareTaker* inputCareTaker = new InputCareTaker();
    InputOriginator* inputOriginator = new InputOriginator();
    
    inputOriginator->setCurrentInput("abc");
    inputCareTaker->saveMemento(inputOriginator->saveCurrentInputToMemento());
    //input abc를 저장
    inputOriginator->setCurrentInput("def");
    inputCareTaker->saveMemento(inputOriginator->saveCurrentInputToMemento());
    //input def를 저장
    inputOriginator->setCurrentInput("ghi");
    
    inputOriginator->restoreFromInputMemento(inputCareTaker->popSavedMemento());
    cout<<"Restore input : "<<inputOriginator->getCurrentInput()<<endl;
    
    inputOriginator->restoreFromInputMemento(inputCareTaker->popSavedMemento());
    cout<<"Restore input : "<<inputOriginator->getCurrentInput()<<endl;
    
    delete inputCareTaker;
    delete inputOriginator;
    
    return 0;
}

실행결과

 

Save Current Input to Memento :abc

Save Current Input to Memento :def

Restore input : def

Restore input : abc

반응형