Featured image of post 14. 다양한 패턴 빠르게 알아보기 - 메멘토 패턴

14. 다양한 패턴 빠르게 알아보기 - 메멘토 패턴

헤드 퍼스트 디자인 패턴

메멘토(Memento) 패턴

객체를 이전 상태로 복구해야 한다면 메멘토(Memento) 패턴을 쓴다. (작업 취소)

메멘토 패턴은 객체의 상태를 저장하고 이를 나중에 복원할 수 있도록 하는 행위 디자인 패턴 중 하나이다.

객체의 상태를 외부하시켜, 생태의 변경을 캡슐화하고 객체의 불변성을 보존한다.

특징

메멘토 객체를 써서 상태를 저장하며, 시스템의 상태를 저장할 때 직렬화를 사용하는 것이 좋다.

  • 상태 저장 및 복원
    • 객체의 내부 상태를 외부로 저장하고, 나중에 이 상태를 사용하여 객체를 복원한다.
  • 캡슐화
    • 객체의 상태를 외부화시켜, 상태 변경을 캡슐화하여 객체의 불변성을 보존한다.

구조

메멘토 패턴 구조

  • Originator(원조자)
    • 현재 상태를 저장하고, 상태를 복원하는 객체를 생성한다.
  • Memento(메멘토)
    • 원조자의 내부 상태를 표현하는 객체이다.
    • 원조자의 상태를 저장하고 복원하기 위해 사용된다.
  • Caretaker(관리자)
    • 메멘토를 관리하고, 필요에 따라 메멘토를 저장하거나 복원한다.

예시

 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
// Memento
public class Memento {
    private String state;

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

    public String getState() {
        return state;
    }
}

// Originator
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 restoreStateFromMemento(Memento memento) {
        state = memento.getState();
    }
}

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

    public void addMemento(Memento memento) {
        mementoList.add(memento);
    }

    public Memento getMemento(int index) {
        return mementoList.get(index);
    }
}

// Client
public class Client {
    public static void main(String[] args) {
        Originator originator = new Originator();
        Caretaker caretaker = new Caretaker();

        originator.setState("State 1");
        originator.setState("State 2");
        caretaker.addMemento(originator.saveStateToMemento());

        originator.setState("State 3");
        caretaker.addMemento(originator.saveStateToMemento());

        System.out.println("Current State: " + originator.getState());

        originator.restoreStateFromMemento(caretaker.getMemento(1));
        System.out.println("Restored State: " + originator.getState());
    }
}

장단점

장점

  • 캡슐화된 상태
    • 객체의 상태가 외부에 의해 캡슐화되어 저장되므로, 객체의 내부 상태를 외부로부터 은닉할 수 있다.
    • 저장된 상태를 핵심 객체와는 다른 별도의 객체에 보관할 수 있어 안전하다.
  • 복원 가능성
    • 객체의 상태를 나중에 복원할 수 있으므로, 객체의 상태를 이전 상태로 쉽게 되돌릴 수 있다.

단점

  • 상태를 저장하고 복구하는 데 시간이 오래 걸릴 수도 있다.
  • 메모리 사용
    • 상태를 저장하기 위한 메멘토 객체를 생성하고관리하는 데 일정한 메모리 비용이 들 수 있다.
  • 복잡성
    • 큰 객체의 상태를 저장하고 복원하는 과정이 복잡해질 수 있다.