[디자인패턴] 행동패턴(9) - Memento Pattern (메멘토 패턴)은 객체 내부 상태를 캡슐화하여 저장하고, 이후 해당 상태로 복원할 수 있게 해주는 디자인 패턴입니다. 예를 들어, Undo/Redo 기능 구현에 자주 사용됩니다.
이번 글에서는 Memento 패턴의 구조, 예시, 장단점을 살펴본 뒤, Python 예제 코드와 함께 자세한 내용을 확인해보겠습니다.
1. 개요
Memento 패턴은 Originator, Memento, Caretaker라는 세 가지 주요 컴포넌트로 구성됩니다. Originator는 상태를 가지는 주체이고, Memento는 Originator의 상태를 저장·복원하기 위한 객체이며, Caretaker는 여러 개의 Memento를 관리하면서 Originator의 상태를 필요할 때 되돌려줄 수 있습니다.
2. 예시
텍스트 에디터에서 작성 중인 문서의 상태를 특정 시점마다 저장하고, 필요하다면 이전 상태로 롤백(Undo)하는 시나리오가 대표적입니다.
# Memento Pattern in Python (GoF 구조 반영)
class Memento:
def __init__(self, state):
self._state = state # Originator의 내부 상태를 보관
def get_state(self):
return self._state
class TextEditor: # Originator
def __init__(self):
self._text = ""
def write(self, new_text):
self._text += new_text
def save(self):
return Memento(self._text) # 현재 상태를 Memento에 저장
def restore(self, memento):
self._text = memento.get_state() # 과거 상태로 복원
def show_text(self):
print("[Python] Current Text:", self._text)
class Caretaker:
def __init__(self):
self._history = []
def add_memento(self, memento):
self._history.append(memento)
def get_memento(self, index):
return self._history[index]
if __name__ == "__main__":
editor = TextEditor()
caretaker = Caretaker()
editor.write("Hello World! ")
caretaker.add_memento(editor.save()) # 첫 번째 상태 저장
editor.write("This is a Memento pattern test. ")
caretaker.add_memento(editor.save()) # 두 번째 상태 저장
editor.show_text()
# 첫 번째 상태로 복원
editor.restore(caretaker.get_memento(0))
editor.show_text()
위 코드에서 TextEditor가 Originator 역할을 하며, Memento 객체를 통해 상태를 저장하고, Caretaker는 여러 개의 Memento를 보관하여 필요 시 과거 상태로 되돌릴 수 있게 합니다.
3. 장점
- Undo/Redo 기능 구현이 쉬워집니다. Originator의 내부 상태를 외부에 노출하지 않고 안전하게 보관할 수 있습니다.
- 캡슐화가 유지되어, Originator의 내부 구조가 변해도 외부에는 영향을 주지 않습니다.
4. 단점
- 메모리 사용 증가: 많은 시점의 상태를 저장하면 Memento 객체가 쌓여서 부담이 될 수 있습니다.
- 관리 복잡성: Caretaker가 여러 개의 Memento를 어떻게 관리·정리하느냐가 추가 고민거리입니다.
5. 결론
Memento 패턴은 Undo/Redo가 필요한 애플리케이션에서 특히 빛을 발합니다. 캡슐화를 지키면서도 과거 상태로 쉽게 되돌아갈 수 있도록 해주므로, 문서 편집기, 그래픽 편집 도구, 게임 상태 저장 등 다양한 분야에서 응용될 수 있습니다. 다만, 많은 상태를 저장하면 메모리 사용량이 증가할 수 있으므로, 보존 주기나 최대 개수 등을 적절히 설계하는 것이 중요합니다.
'Study > Software Architecture' 카테고리의 다른 글
[디자인패턴] 행동패턴(11) - Chain of Responsibility Pattern (책임 연쇄 패턴) (0) | 2023.06.12 |
---|---|
[디자인패턴] 행동패턴(10) - Observer Pattern (옵져버 패턴, 관찰자 패턴) (0) | 2023.06.12 |
[디자인패턴] 구조패턴(7) - Flyweight Pattern (플라이웨이트 패턴) (0) | 2023.06.06 |
[디자인패턴] 구조패턴(6) - Facede Pattern (파사드 패턴) (0) | 2023.06.05 |
[디자인패턴] 구조패턴(5) - Decorator Pattern (데코레이터 패턴) (0) | 2023.05.26 |