티스토리 뷰

메멘토 패턴이란?

메멘토 패턴은 객체의 구현 세부 사항 공개하지 않으면서 해당 객체의 이전 상태를 저장하고 복원할 수 있게 해주는 패턴이다. 객체를 이전 상태로 복원할 수 있도록 상태 정보를 어딘 가에 저장해야 한다. 그러나 객체는 일반적으로 상태의 일부 또는 전부를 캡슐화하므로 다른 객체에 액세스할 수 없고 외부에 저장할 수 없다. 이 상태를 노출하면 캡슐화를 위반하여 애플리케이션의 안정성과 확장성을 손상시킬 수 있기 때문이다.

 

 

메멘토 패턴 사용 법

  • Originator
    • Memento를 이용해 스냅샷들을 생성한다.
    • Memento를 이용해 복원할 수도 있다. 
  • Memento
    • Originator 객체의 스냅샷 역할을 하는 값 객체.
    • Originator 객체 이외의 다른 객체(CareTaker)에서 상태 정보로의 접근을 제한한다.
  • Caretaker
    • Memento 객체들을 보관하거나 관리할 수 있어 상태가 복원돼야 하는 시기도 알 고 있다. 
    • Memento 객체들을 생성하거나, 내부정보에 접근할 수 없다.
public class Originator {
    private String state;

    public void setState(String state){
        this.state = state;
    }

    public String getState(){
        return state;
    }

    public Memento saveStateToMemento(){
        return new Memento(state);
    }

    public void getStateFromMemento(Memento memento){
        state = memento.getState();
    }
}

public class Memento {
    private String state;

    public Memento(String state){
        this.state = state;
    }

    public String getState(){
        return state;
    }
}

public class CareTaker {
    private List<Memento> mementoList = new ArrayList<Memento>();

    public void add(Memento state){
        mementoList.add(state);
    }

    public Memento get(int index){
        return mementoList.get(index);
    }
}
 public static void main(String[] args) {
        Originator originator = new Originator();
        CareTaker careTaker = new CareTaker();
        originator.setState("State #1");
        originator.setState("State #2");
        careTaker.add(originator.saveStateToMemento());
        originator.setState("State #3");
        careTaker.add(originator.saveStateToMemento());
        originator.setState("State #4");

        System.out.println("Current State: " + originator.getState());
        originator.getStateFromMemento(careTaker.get(0));
        System.out.println("First saved State: " + originator.getState());
        originator.getStateFromMemento(careTaker.get(1));
        System.out.println("Second saved State: " + originator.getState());
}

Caretaker 객체가 Originator 객체에게 Memento 객체 생성을 요청한다. 생성된 Memento 객체를 관리하고 필요 시 Originator 객체의 상태를 되돌리는데 Memento 객체를 이용한다.
Memento 는 수동적이다. 단지 Originator 객체만이 Memento 를 생성하고, 상태정보를 지정하거나 얻어올 수 있다.

패턴 사용 시기

  • 메멘토는 객체의 이전 상태를 복원할 수 있도록 객체의 상태의 스냅샷들을 생성하려는 경우
  • 이 패턴은 또 객체의 필드들, 게터들, 세터들을 직접 접근하는 것이 해당 객체의 캡슐화를 위반할 때

패턴 장점

  • 저장된 상태를 핵심 객체와는 다른 별도의 객체에 보관하기 때문에 안전하다.
  • 핵심 객체의 데이터를 계속해서 캡슐화된 상태로 유지할 수 있다.
  • 복구 기능을 구현하기 쉽다.

패턴 단점

  • 이전 상태의 객체를 저장하기 위한 Originator가 클 경우 많은 메모리가 필요하다.
  • 상태를 저장하고 복구하는데 시간이 오래 걸릴 수 있다.
    • 자바 시스템에서는 시스템의 상태를 저장할 때 직렬화를 사용하는 것이 좋다.