본문 바로가기

Design Patterns/영문 위키(Wikipedia)

Memento pattern

먼저 이 글은 영문 위키의 글은 번역한 글임을 알려드립니다.

영어 실력이 부족한 관계로 오역이 있을 수도 있습니다.

원문 주소 : http://en.wikipedia.org/wiki/Memento_pattern



Behavioral - Memento pattern



memento 패턴은 객체의 이전 상태를 저장하는 방법을 제공하는 소프트웨어 디자인 패턴(software design pattern)이다. (롤백을 통한 취소(undo)와 같은 예가 있다.)


memento 패턴은 originator(창작자, 시조)와 caretaker(경비원, 관리인)라는 두개의 객체로 구현된다. Originator는 내부 상태(state)를 가지고 있는 객체이다. Caretaker는 originator에게 어떤 동작을 하지만 변화에 대해 취소하고 싶어한다. caretaker는 먼저 originator에게 memento객체를 요청한다. 그러면 caretaker가 어떤 일을 하려고했던지 상관없이 그 동작을 수행한다. 동작이 일어나기 전 상태로 되돌리기 위해 caretaker는 originator에게 memento객체를 반환한다. memento객체는 불투명한 객체(opaque object)이다. (caretaker는 memento객체를 변경할 수 없기 때문에). 이 패턴을 사용할 때 originator가 다른 객체나 자원(resources)을 변경할 수 있다면 주의를 기울여야 한다.(memento 패턴은 한 특정 객체안에서 동작한다.)


memento 패턴에 대한 전형적인 예에는 pseudorandom number generator 의 씨앗(seed, 랜덤 숫자를 생성할 때 사용하는 일종의 key라고 생각하면 되겠네요.)과 finite state machine의 상태가 있다.

예 Example

아래의 예는 Memento 패턴의 "undo"사용법을 묘사하고 있는 Java 프로그램이다.

import java.util.List;
import java.util.ArrayList;
class Originator {
    private String state;
    // The class could also contain additional data that is not part of the
    // state saved in the memento.
 
    public void set(String state) {
        System.out.println("Originator: Setting state to " + state);
        this.state = state;
    }
 
    public Memento saveToMemento() {
        System.out.println("Originator: Saving to Memento.");
        return new Memento(state);
    }
 
    public void restoreFromMemento(Memento memento) {
        state = memento.getSavedState();
        System.out.println("Originator: State after restoring from Memento: " + state);
    }
 
    public static class Memento {
        private final String state;
 
        public Memento(String stateToSave) {
            state = stateToSave;
        }
 
        public String getSavedState() {
            return state;
        }
    }
}
 
class Caretaker {
    public static void main(String[] args) {
        List savedStates = new ArrayList();
 
        Originator originator = new Originator();
        originator.set("State1");
        originator.set("State2");
        savedStates.add(originator.saveToMemento());
        originator.set("State3");
        // We can request multiple mementos, and choose which one to roll back to.
        savedStates.add(originator.saveToMemento());
        originator.set("State4");
 
        originator.restoreFromMemento(savedStates.get(1));   
    }
}



결과는 아래와 같다.

Originator: Setting state to State1
Originator: Setting state to State2
Originator: Saving to Memento.
Originator: Setting state to State3
Originator: Saving to Memento.
Originator: Setting state to State4
Originator: State after restoring from Memento: State3



이 예에서는 상태를 표현하기 위해 String 클래스를 사용하고 있다.(이는 자바에서 기본적으로 immutable type(변하지 않는 타입)이다.) 실제 시나리오에서 상태는 대게는 특정 객체가 되어야 한다. 그래서 memento 객체에 넣기 전에 상태객체는 복제해서 넣어야한다.

 private Memento(State state)
        {
            //state has to be cloned before returning the 
            //memento, or successive calls to get Memento
            //return a reference to the same object
            this.mementoState = state.clone();
 
        }


'Design Patterns > 영문 위키(Wikipedia)' 카테고리의 다른 글

State pattern  (0) 2012.07.03
Observer pattern  (0) 2012.06.27
Mediator pattern  (0) 2012.06.19
Iterator pattern  (0) 2012.06.18
Interpreter pattern  (0) 2012.06.15