Memento Pattern

Memento Pattern 은 행위 디자인 패턴 중 하나로, 객체의 상태를 저장하고 이전 상태로 복원할 수 있게 해주는 패턴이다.

메멘토 패턴 (Memento Pattern) 은 소프트웨어 디자인 패턴 중 하나로, 객체의 상태를 저장하고 나중에 복원할 수 있는 메커니즘을 제공한다.
이 패턴의 주요 목적은 객체의 내부 상태를 캡슐화하면서도 외부에서 해당 상태를 저장하고 복원할 수 있게 하는 것이다.

메멘토 패턴은 객체의 상태 관리와 복원이 중요한 애플리케이션에서 매우 유용한 디자인 패턴이다.
이 패턴을 적절히 활용하면 코드의 유연성과 유지보수성을 크게 향상시킬 수 있다.

주요 구성 요소

메멘토 패턴은 세 가지 주요 구성 요소로 이루어져 있다:

동작 방식

Originator 객체의 상태를 Memento 에 저장하고, 이후에 복원할 수 있다.
Memento 객체는 Originator 객체 외부에서 직접적으로 접근할 수 없으며, Caretaker 객체를 통해서만 접근할 수 있다.
따라서, 상태를 안전하게 보호하면서도 필요한 경우에만 복원할 수 있다.

기본적인 Memento 패턴의 구조

 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
# Memento: 상태를 저장하는 클래스
class EditorMemento:
    def __init__(self, content: str):
        # 에디터의 상태를 저장
        self._content = content
    
    def get_saved_content(self) -> str:
        return self._content

# Originator: 상태를 가지고 있는 원본 객체
class TextEditor:
    def __init__(self):
        self._content = ""
    
    def write(self, text: str) -> None:
        self._content += text
    
    def get_content(self) -> str:
        return self._content
    
    # 현재 상태를 저장
    def save(self) -> EditorMemento:
        return EditorMemento(self._content)
    
    # 이전 상태로 복원
    def restore(self, memento: EditorMemento) -> None:
        self._content = memento.get_saved_content()

# Caretaker: Memento 객체들을 관리
class History:
    def __init__(self):
        self._mementos = []
    
    def push(self, memento: EditorMemento) -> None:
        self._mementos.append(memento)
    
    def pop(self) -> EditorMemento:
        return self._mementos.pop()

실제 사용 예시:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# 텍스트 에디터에서의 실행 취소 기능 구현
def editor_example():
    editor = TextEditor()
    history = History()
    
    # 텍스트 작성 및 상태 저장
    editor.write("First sentence. ")
    history.push(editor.save())
    
    editor.write("Second sentence. ")
    history.push(editor.save())
    
    editor.write("Third sentence. ")
    print("Current content:", editor.get_content())
    
    # 실행 취소 (이전 상태로 복원)
    editor.restore(history.pop())
    print("After first undo:", editor.get_content())
    
    editor.restore(history.pop())
    print("After second undo:", editor.get_content())

장점

단점

사용 사례

이 패턴은 복잡한 상태를 가진 객체에서 매우 유용하다.
예를 들어, 텍스트 편집기에서 사용자가 작성한 문서의 상태를 저장하고 이전 상태로 복원하는 경우, 메멘토 패턴을 사용할 수 있다. 또한, 게임에서 플레이어의 게임 상태를 저장하고 이전 상태로 복원하는 경우에도 이 패턴을 사용할 수 있다.

구현 시 고려사항


용어 정리

용어설명

참고 및 출처


1. 주제의 분류 적절성

Memento Pattern(메멘토 패턴) 은 “Computer Science and Engineering > Software Design and Architecture > Software Design Patterns > GoF > Behavioral Design Patterns” 분류에 정확히 해당합니다. GoF(Gang of Four) 에서 정의한 대표적인 행동 (Behavioral) 패턴 중 하나로, 객체의 상태 관리와 복원에 초점을 둡니다 [1][2][4].


2. 200 자 요약

메멘토 패턴은 객체의 내부 상태를 외부에 노출하지 않고 저장 및 복원할 수 있도록 하는 디자인 패턴입니다. 주로 Undo/Redo, 스냅샷, 버전 관리 등 상태 복원이 필요한 시스템에서 활용되며, 캡슐화 원칙을 지키면서 객체의 상태 이력을 관리할 수 있습니다 [1][2][4][7].


3. 250 자 개요

메멘토 패턴은 객체의 내부 구현을 외부에 노출하지 않고, 특정 시점의 상태를 저장 (Memento) 하고 필요시 복원할 수 있도록 하는 행동 패턴입니다. Originator(원본 객체) 가 상태를 캡처해 Memento(메멘토) 에 저장하고, Caretaker(관리자) 가 이를 보관합니다. Undo/Redo, 트랜잭션 롤백, 버전 관리 등 다양한 분야에서 활용되며, 캡슐화와 단일 책임 원칙을 지키면서 객체의 상태 이력을 안전하게 관리할 수 있습니다 [1][2][4][12].


핵심 개념


주요 내용 정리

패턴 이름과 분류

항목내용
패턴 이름Memento Pattern (메멘토 패턴)
분류GoF 행동 (Behavioral) 패턴

의도 (Intent)

캡슐화를 위반하지 않고 객체의 내부 상태를 외부에 저장·복원할 수 있도록 하여, 객체를 이전 상태로 되돌릴 수 있게 한다 [1][2][4].


다른 이름 (Also Known As)


동기 (Motivation / Forces)


적용 가능성 (Applicability)


구조 및 아키텍처

구조 다이어그램

1
2
3
4
5
6
7
8
+-------------------+         +------------------+
|   Caretaker       ||   Memento        |
+-------------------+         +------------------+
         ^                              ^
         |                              |
+-------------------+         +------------------+
|   Originator      ||   (state)        |
+-------------------+         +------------------+

UML 클래스 다이어그램

1
2
3
4
[Originator]  [Memento]
     ^                   ^
     |                   |
[ Caretaker ]  |

구성 요소 및 역할

구성 요소기능 및 역할
Originator상태를 저장 및 복원하는 객체. Memento 를 생성하고, 필요 시 상태를 복원함 [1][2][4][12]
MementoOriginator 의 상태를 저장하는 객체. 상태 정보는 외부에 노출되지 않음 [1][2][4][12]
CaretakerMemento 를 보관 및 관리. 내부 상태에는 접근하지 않고, 저장/복원 시 Originator 에 전달 [1][2][4][12]

필수/선택 구성요소

구분구성 요소기능 및 특징
필수Originator상태 저장/복원, Memento 생성 및 복원 메서드 구현
필수Memento상태 스냅샷 저장, 불변 객체로 설계 (권장)
필수CaretakerMemento 보관, 관리, 내부 상태에는 접근 불가
선택History 관리Memento 의 리스트/스택 관리 (Undo/Redo 등)

주요 원리 및 작동 원리

  1. 상태 저장: Caretaker 가 Originator 에 상태 저장 요청 → Originator 가 Memento 생성 및 반환 → Caretaker 가 Memento 보관
  2. 상태 복원: Caretaker 가 Originator 에 상태 복원 요청 → Originator 가 Memento 를 받아 상태 복원

작동 원리 다이어그램

1
2
3
4
5
6
7
[ Caretaker ]
     |             상태 저장 요청
     v
[ Originator ] --(상태 저장)--> [ Memento ]
     ^                              |
     |             상태 복원 요청    |
     +------------------------------+

구현 기법

예시 코드 (Python)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Memento:
    def __init__(self, state):
        self._state = state
    def get_state(self):
        return self._state

class Originator:
    def __init__(self):
        self._state = None
    def set_state(self, state):
        self._state = state
    def save(self):
        return Memento(self._state)
    def restore(self, memento):
        self._state = memento.get_state()

class Caretaker:
    def __init__(self):
        self._history = []
    def backup(self, memento):
        self._history.append(memento)
    def undo(self):
        return self._history.pop() if self._history else None

장점과 단점

구분항목설명
✅ 장점캡슐화 보장내부 상태 노출 없이 상태 저장/복원 가능
Undo/Redo 지원상태 이력 관리, 복원 기능 손쉽게 구현
코드 단순화Originator 와 Caretaker 책임 분리, 관리 용이
⚠ 단점메모리 사용 증가상태가 많거나 무거우면 메모리 부담
관리 복잡성Memento 수명, 삭제, 관리 필요
언어 한계일부 언어에서 캡슐화 보장 어려움

도전 과제 및 해결책


분류에 따른 종류 및 유형

분류 기준종류/유형설명
상태 저장 방식전체 스냅샷전체 상태 저장 (기본)
차등 스냅샷변경분만 저장 (메모리 최적화)
관리 방식단일 상태최근 상태 1 개만 저장
다중 상태 (이력)여러 상태 스택/리스트로 관리 (Undo/Redo)

실무 적용 예시

분야적용 예시설명
텍스트 에디터Undo/Redo 기능입력, 삭제, 변경 이력 관리
게임세이브/로드, 체크포인트게임 진행 상태 스냅샷 저장/복원
데이터베이스트랜잭션 롤백작업 실패 시 이전 상태로 복원
워크플로우단계별 상태 저장단계별로 상태 저장 및 복원

활용 사례 (시나리오 기반)

상황 가정: 텍스트 에디터 Undo/Redo


실무에서 효과적으로 적용하기 위한 고려사항 및 주의점

항목설명권장사항
메모리 관리상태가 많거나 크면 메모리 부담필요 최소한의 상태만 저장, 오래된 이력 삭제
이력 관리Undo/Redo 등 이력 관리 필요스택/리스트 등 자료구조 활용, 이력 제한
캡슐화 보장Memento 접근 제한 필요내부 클래스, 접근 제어자 활용
상태 복원 테스트복원 시 일관성 유지 필요단위 테스트, 복원 검증 강화

최적화하기 위한 고려사항 및 주의점

항목설명권장사항
스냅샷 최적화전체 상태 저장 시 오버헤드 발생차등 저장, 압축 등 최적화 적용
이력 관리이력 길이 증가 시 성능 저하 가능이력 제한, 오래된 이력 정리
불필요한 복원 방지불필요한 Undo/Redo 호출 방지상태 변경 감지 후에만 스냅샷 저장
GC 연동Memento 객체 누수 방지GC/만료 정책 등 자원 관리 적용

2025 년 기준 최신 동향

주제항목설명
Undo/Redo대용량 이력 관리대용량 이력 관리 및 압축 스냅샷 기법 활용 증가
클라우드/분산분산 상태 스냅샷분산 시스템에서의 상태 스냅샷 관리 기술 발전
프레임워크Undo/Redo 라이브러리다양한 언어/프레임워크에서 Undo/Redo 지원 강화
성능차등 스냅샷/압축메모리 절약을 위한 차등 저장, 압축 기법 확산

주제와 관련하여 주목할 내용

주제항목설명
캡슐화내부 상태 보호외부에 내부 상태 노출 없이 상태 복원 지원
Undo/Redo이력 관리다양한 애플리케이션에서 Undo/Redo 표준화
연관 패턴Command, IteratorCommand 와 결합해 Undo, Iterator 와 결합해 반복 상태 관리
차등 저장메모리 최적화변경분만 저장해 메모리 사용 절감

앞으로의 전망

주제항목설명
대규모 시스템분산 상태 관리분산 환경에서의 상태 스냅샷/복원 기술 발전
자동화이력 관리 자동화이력/스냅샷 관리 자동화 도구 확산
성능고성능 스냅샷대용량 데이터의 효율적 상태 저장/복원 연구 증가
보안안전한 이력 관리민감 정보 보호, 안전한 스냅샷 관리 기법 발전

하위 주제별 추가 학습 필요 내용

카테고리주제간략 설명
패턴 구조내부 클래스 활용캡슐화 강화를 위한 내부 클래스 설계법
이력 관리차등 스냅샷변경분만 저장하는 기법
연관 패턴Command, IteratorUndo/Redo, 반복 상태 관리와의 결합
테스트상태 복원 검증복원 일관성 및 신뢰성 테스트 전략

추가 학습/알아야 할 내용

카테고리주제간략 설명
소프트웨어 아키텍처분산 스냅샷분산 시스템에서의 상태 저장/복원 전략
성능압축/최적화대용량 상태 스냅샷의 압축 및 최적화 기법
프레임워크Undo/Redo 라이브러리다양한 언어/프레임워크에서의 활용법
실무 도구이력/스냅샷 관리 도구실무 적용 가능한 이력/스냅샷 관리 도구

용어 정리

용어설명
Originator(원본 객체)상태 저장/복원 기능을 가진 객체
Memento(메멘토)Originator 의 상태 스냅샷을 저장하는 객체
Caretaker(관리자)Memento 를 보관·관리하는 객체, 내부 상태에는 접근 불가
차등 스냅샷 (Differential Snapshot)변경된 부분만 저장하는 방식
캡슐화 (Encapsulation)객체의 내부 구현을 외부에 노출하지 않는 원칙

참고 및 출처

**Memento Pattern (메멘토 패턴)**에 대해 실무 기반으로 심층 분석한 내용을 다음과 같이 정리하였습니다.


1. 주제의 분류 적절성 검토


2. 요약 설명 (200 자 내외)

메멘토 패턴은 객체의 상태를 저장하고 복원할 수 있도록 하며, 캡슐화를 유지하면서도 상태 관리 기능을 제공합니다. 실행 취소 (Undo), 버전 관리, 상태 롤백 등에서 활용되며, Caretaker-Originator-Memento 구조로 구현됩니다.


3. 개요 설명 (250 자 내외)

Memento Pattern 은 객체의 내부 상태를 외부에 노출하지 않고도 저장 및 복원이 가능하게 해주는 디자인 패턴입니다. 상태 캡처와 복구를 지원하며, 실행 취소 (Undo), Redo, 상태 백업 등의 기능 구현에 효과적입니다. 이 패턴은 객체의 상태를 저장하는 Memento, 상태를 저장하고 복원하는 Originator, 상태를 관리하는 Caretaker 세 구성요소로 구성됩니다. 개발 실무에서는 텍스트 편집기, 게임 저장, 워크플로우 엔진 등 다양한 분야에 활용됩니다.


4. 핵심 개념

요소설명
MementoOriginator 의 상태를 저장하는 객체. 외부에서는 수정 불가
Originator상태를 생성하고, 필요 시 Memento 를 통해 상태를 복원
CaretakerMemento 객체를 보관하고 복원 요청 시 전달함. 상태 내용에는 접근 불가

핵심 원칙


5. 주요 내용 정리

목적 및 필요성

주요 기능 및 역할

특징


주요 원리 및 작동 원리 다이어그램

1
2
3
4
5
6
7
+---------------+     creates     +-------------+
|  Originator   |---------------->|   Memento   |
+---------------+     restores    +-------------+
        ^                               |
        |     stores/retrieves          |
        +-------------------------------+
                    Caretaker

구조 및 아키텍처

구성요소설명
Originator현재 상태를 가진 객체로, 상태 저장 및 복원을 담당
MementoOriginator 의 상태를 저장하는 불변 객체
Caretaker상태 이력을 관리하지만 내부 구현에는 접근 불가

필수 구성 요소

선택 구성 요소


구현 기법

항목설명
정의상태를 캡처한 Memento 객체를 통해 Originator 가 상태 복원을 수행
구성Memento 는 내부 상태만을 저장, 외부 수정 불가
목적복원 가능한 상태 스냅샷 기능 구현
실무 예시워드 프로세서의 실행 취소, 게임 저장, Form 편집 상태 보존

장단점

구분항목설명
✅ 장점캡슐화 유지객체의 내부 상태를 외부에 노출하지 않고 저장 가능
Undo/Redo 구현 용이상태 복원을 통해 사용자의 실수 복구가 가능
상태 스냅샷 설계복잡한 상태 전이 없이 상태 백업/복원 기능 제공
⚠ 단점메모리 부담상태 객체가 클 경우 Memento 객체 크기 증가
상태 이력 관리 필요Caretaker 에서 상태 이력 관리를 명확히 해야 함
구조 복잡도 증가단순한 시스템에 도입 시 과설계 가능성 있음

도전 과제

도전 과제설명해결책
상태 저장 비용 증가대용량 객체 상태 복사 시 성능 저하변경된 부분만 저장하는 Delta 방식 적용
불필요한 상태 저장의미 없는 상태까지 저장할 가능성상태 변경 감지 후 저장 조건 설정
Undo/Redo 충돌복원된 상태가 현재 상태와 충돌 가능Memento 설계 시 정합성 검증 포함 필요

분류에 따른 종류 및 유형

분류 기준유형설명
저장 방식Full Snapshot전체 상태 복사 (일반적)
Delta Storage변경된 차이만 저장 (메모리 절약)
상태 대상단일 상태객체 단일 속성 저장
복합 상태복잡한 객체 그래프 전체 저장 가능

실무 적용 예시

분야적용 사례설명
텍스트 편집기실행 취소/복원 기능편집 상태 이력 저장 및 복원
워크플로우 엔진상태 롤백오류 발생 시 이전 상태로 복귀
게임 저장Checkpoint 기능특정 시점의 캐릭터/환경 상태 저장
설정 관리 시스템이전 설정 복원사용자 설정 변경 전 상태 저장 및 복원

다음에는 활용 사례 시나리오, 적용 고려사항, 성능 최적화, 최신 동향, 향후 전망, 학습 주제 분류를 이어서 정리하겠습니다. 계속 진행할까요?
이어서 Memento Pattern (메멘토 패턴) 에 대한 심화 내용을 정리합니다.


6. 활용 사례 (시나리오 기반)

📌 시나리오: 문서 편집기에서 실행 취소 (Undo) 기능 구현

🧩 시스템 구성 요소

컴포넌트설명
Editor (Originator)현재 문서 상태 (텍스트) 를 보유, 저장 및 복원 기능 담당
EditorMemento (Memento)Editor 의 상태를 저장하는 객체, 불변 객체로 설계
HistoryManager (Caretaker)상태 이력을 저장하는 스택, 복원 요청 시 Memento 전달

📊 시스템 구성 다이어그램

1
2
3
4
5
6
7
+-------------+        +------------------+         +----------------+
|  History    |<------>|   Editor         |<------->| EditorMemento  |
| (Caretaker) |        | (Originator)     |         |  (Memento)     |
+-------------+        +------------------+         +----------------+
| +push(m)    |        | +createMemento() |         |  getState()    |
| +pop()      |        | +restore(m)      |         |  (read-only)   |
+-------------+        +------------------+         +----------------+

⚙️ 워크플로우

  1. 사용자가 문서를 수정하면 EditorEditorMemento 생성

  2. HistoryManager 가 해당 상태를 스택에 저장

  3. 사용자가 Undo 시 HistoryManager 에서 마지막 상태를 꺼내 Editor 에 복원


7. 실무에서 효과적으로 적용하기 위한 고려사항

고려사항설명권장사항
상태 저장 전략전체 상태를 저장할지, 일부만 저장할지 결정 필요큰 객체는 변경된 필드만 저장 (delta 방식)
메멘토 수 제한상태가 많을 경우 메모리 낭비 발생 가능히스토리 길이 제한 또는 압축 적용
상태 정합성 보장복원 시 다른 시스템과의 일관성 고려 필요저장 시점에서 외부 상태 검증 포함
메멘토 접근 제어외부에서 메멘토 내용 변경 금지내부 클래스 또는 접근자 제한 적용 (private/protected)

8. 성능을 최적화하기 위한 고려사항

고려사항설명권장사항
메멘토 크기객체 상태가 클수록 메모리 사용량 증가필요한 속성만 선택적으로 저장
스냅샷 빈도너무 자주 저장하면 리소스 과다 사용변경 여부 감지 후 저장 조건 추가
GC 영향저장된 메멘토가 많으면 GC 부담 증가오래된 상태 주기적 삭제, LRU 전략 도입
이력 관리무한 저장 시 성능 저하 우려스택 깊이 제한 또는 히스토리 관리 정책 적용

9. 2025 년 기준 최신 동향

주제항목설명
상태 기반 UIUndo/Redo 지원 강화React/Flutter 등 선언형 UI 에서 상태 스냅샷 기능 도입
저장소 추상화상태 이력의 외부화로컬이 아닌 Redis, DB 에 상태 저장하여 확장성 확보
버저닝 시스템JSON 기반 상태 백업 증가Git-like 스냅샷 저장을 JSON 으로 구현하는 시스템 증가
워크플로우상태 전이 복원 기능 고도화BPMN, Camunda 등에서 Memento 유사 기능 내장 제공

10. 앞으로의 전망

주제항목설명
클라우드 통합상태 저장의 중앙 집중화상태를 외부 저장소 (S3, DynamoDB) 로 전환하여 안정성 확보
협업 기능 강화버전 간 병합 알고리즘 도입메멘토 복원 시 사용자 병합 전략 (3-way merge) 채택 증가
AI + 상태 예측AI 기반 상태 추천 기능이전 상태 기반 자동 복원 또는 예측 Undo 기능 연구 중
상태 기록 시각화GUI 기반 롤백 관리 UI사용자에게 이전 상태 선택 및 비교 기능 제공 확대

11. 하위 주제별 학습 분류

카테고리주제설명
디자인 패턴상태 저장 및 복원메멘토, 커맨드, 상태 패턴 비교
자료 구조스택 기반 히스토리 관리Undo/Redo 를 위한 자료구조 구성법
객체 설계캡슐화된 객체 상태내부 상태 보존과 외부 인터페이스 분리 설계
직렬화상태 저장의 영속성 처리JSON, binary 형식으로 상태 저장 기술 이해

12. 확장 학습 주제 (실무 연관)

카테고리주제설명
백엔드 아키텍처상태 기반 시스템 설계상태 롤백, 상태 마이그레이션 시나리오 설계
메시지 처리이벤트 소싱 vs Memento상태 복원 방식별 장단점 비교
테스트 전략상태 스냅샷 기반 테스트특정 상태에서 테스트 반복 실행 전략
데이터 관리버전 관리 vs 메멘토Git, DB 버저닝과 메멘토 패턴의 사용 목적 차이

용어 정리

용어설명
Memento객체의 내부 상태를 캡슐화하여 저장하는 불변 객체
Originator상태를 생성하고 복원하는 역할의 주체 객체
Caretaker상태 이력을 관리하며 직접적으로 상태에 접근하지 않음
Snapshot객체의 상태를 특정 시점에 저장한 복사본
Delta상태의 전체가 아닌 변경된 부분만을 저장하는 방식

참고 및 출처


필요하시면 다음과 같은 자료도 추가로 제공 가능합니다:

좋습니다. 아래에 Memento 패턴 vs Command 패턴 비교Undo/Redo 기능 아키텍처 설계 예제를 정리했습니다.


✅ Memento 패턴 Vs Command 패턴 비교

구분항목Memento 패턴Command 패턴
📌 핵심 목적상태 복원요청 실행 및 되돌리기
🧠 개념객체의 상태를 캡슐화하여 복원 가능하게 함요청 (행위) 를 객체로 캡슐화하고 실행/취소 기능 구현
🔁 Undo 처리상태를 스냅샷으로 저장하고 복원실행 전/후에 별도 undo 로직을 구현
⚙️ 구성요소Originator, Memento, CaretakerCommand, ConcreteCommand, Receiver, Invoker
💾 저장 정보내부 상태 (데이터)행위 정보 (execute/undo 메서드)
🧩 상태 보존 방식상태 전체 혹은 delta 저장명령 로직을 포함한 undo 메서드 구현
🔒 캡슐화상태는 외부에서 직접 접근 불가Command 객체가 외부와 인터페이스로 연결됨
🛠️ 사용 예텍스트 편집기, 게임 저장, 워크플로우 롤백매크로, 트랜잭션 관리, 작업 큐
🔗 의존성상태 중심행동 중심 (행위 객체화)
📉 단점상태 크기 커질 경우 메모리 부담모든 명령마다 undo 구현 필요, 복잡성 증가

🔍 요약

  • Memento는 " 데이터 중심 " 이며 객체의 상태를 복원합니다.

  • Command는 " 행위 중심 " 이며 요청 자체를 캡슐화하고 실행/취소를 제어합니다.


✅ Undo/Redo 기능의 아키텍처 설계 예제

🎯 요구 사항


🧱 아키텍처 구성

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
+------------------+
|     Client       |
+------------------+
        |
        v
+------------------+
|   CommandManager |  <-- Invoker
+------------------+
| undoStack        |
| redoStack        |
+------------------+
   |         |
   v         v
Command    Command
(undo)     (redo)
   |           |
   v           v
Receiver <---> Domain Object

📦 구성 요소 설명

컴포넌트역할
CommandManager명령을 실행하고 undo/redo 스택 관리
Command공통 인터페이스: execute(), undo()
ConcreteCommand각 도메인 명령 구현체 (AddTextCommand, DeleteCommand 등)
Receiver명령이 실제로 수행되는 대상 객체 (Editor, Canvas 등)
undoStack실행된 명령 저장 (LIFO)
redoStack취소된 명령 저장, 재실행 가능

📋 시나리오 플로우 예시

  1. InsertTextCommand("Hello") 실행

    • execute() 실행 후 undoStack 에 push
  2. 사용자 Undo 클릭

    • undoStack.pop().undo() 실행 → redoStack 에 push
  3. 사용자 Redo 클릭

    • redoStack.pop().execute() 실행 → 다시 undoStack 에 push

🧪 확장 고려사항

항목설명
복합 명령 (MacroCommand)여러 Command 를 묶어서 하나의 작업으로 취소/재실행 가능
상태 저장 vs 행위 저장Undo 가 상태 복원 방식이면 Memento 패턴 병행 적용 가능
저장 방식 선택큰 데이터는 Delta 방식, 단순 명령은 Command 방식 사용 권장
UI 적용Ctrl+Z, Ctrl+Y 등 키보드 단축키와의 연결 포함 가능

🔁 두 패턴 통합 전략 (하이브리드)

복잡한 Undo/Redo 시스템에서는 Memento + Command 패턴을 함께 사용하는 것이 실무적입니다.

✅ 예:
InsertTextCommand 는 실행 시 Editor.createMemento() 를 통해 상태 저장 → Undo 시 restoreMemento()


필요하시면 다음 항목도 추가 제공 가능합니다:

메모리 패턴 (Memento Pattern) 에 대해 상세히 조사하고 분석해드리겠습니다.

이제 조사한 내용을 바탕으로 메멘토 패턴에 대한 포괄적인 분석을 진행하겠습니다.

메멘토 패턴 (Memento Pattern) 종합 분석

1. 주제 분류 검증

제시된 주제 분류 **“Computer Science and Engineering” > “Software Design and Architecture” > “Software Design Patterns” > “GoF” > “Behavioral Design Patterns”**는 적절합니다. 메멘토 패턴은 Gang of Four(GoF) 에서 정의한 23 가지 디자인 패턴 중 하나로, 행동 디자인 패턴 (Behavioral Design Pattern) 범주에 속합니다.

2. 요약 문장 (200 자 내외)

메멘토 패턴 (Memento Pattern) 은 객체의 내부 상태를 캡슐화를 위반하지 않으면서 외부로 노출시켜 저장하고, 나중에 해당 상태로 복원할 수 있게 하는 행동 디자인 패턴입니다. 실행 취소 (Undo), 롤백 (Rollback), 체크포인트 기능을 구현할 때 주로 사용되며, Originator, Memento, Caretaker 세 가지 핵심 구성요소로 이루어집니다.

3. 전체 개요 (250 자 내외)

메멘토 패턴은 토큰 패턴 (Token Pattern) 이라고도 불리며, 객체의 상태를 스냅샷으로 저장하고 복원하는 기능을 제공합니다. 텍스트 에디터의 실행 취소, 게임의 세이브/로드, 데이터베이스 트랜잭션 롤백 등에 활용됩니다. 패턴은 상태를 생성하는 Originator, 상태를 저장하는 Memento, 메멘토를 관리하는 Caretaker 로 구성되어 객체 간의 캡슐화를 유지하면서 상태 관리를 효율적으로 수행합니다.

4. 핵심 개념

기본 개념

심화 개념


Part 1: 핵심 이론 및 원리

배경

메멘토 패턴은 1995 년 Gang of Four 가 “Design Patterns: Elements of Reusable Object-Oriented Software” 에서 소개한 23 가지 디자인 패턴 중 하나입니다. 이 패턴의 개발 배경은 다음과 같습니다:

목적 및 필요성

주요 목적

  1. 캡슐화 보존: 객체의 내부 구조를 외부에 노출하지 않으면서 상태 저장
  2. 상태 복원: 객체를 이전 상태로 안전하게 되돌리는 기능 제공
  3. 책임 분리: 상태 저장과 관리 책임을 명확히 분리

필요성

주요 기능 및 역할

핵심 기능

  1. 상태 스냅샷 생성: 특정 시점에서 객체의 상태를 캡처
  2. 상태 저장 및 관리: 생성된 스냅샷을 안전하게 저장하고 관리
  3. 상태 복원: 저장된 스냅샷을 사용하여 객체 상태를 복원
  4. 이력 관리: 여러 상태 변화의 이력을 순차적으로 관리

역할 분담

특징

주요 특징

  1. 캡슐화 유지: 객체의 내부 상태에 직접 접근하지 않음
  2. 불변성: Memento 객체는 생성 후 변경되지 않음
  3. 투명성: Caretaker 는 Memento 의 내용을 알 수 없음
  4. 단일 객체 중심: 한 번에 하나의 객체 상태만 처리

고유 특성

핵심 원칙

기본 원칙

  1. 단일 책임 원칙 (SRP): 각 구성 요소가 명확한 단일 책임을 가짐
  2. 개방 - 폐쇄 원칙 (OCP): 새로운 상태 관리 요구사항에 대해 확장 가능
  3. 캡슐화 원칙: 객체의 내부 상태를 외부로부터 보호

설계 원칙

주요 원리 및 작동 원리

작동 메커니즘

1
2
3
4
5
1. 상태 저장 과정:
   Client → Caretaker → Originator.createMemento() → Memento 생성
   
2. 상태 복원 과정:
   Client → Caretaker → Originator.restore(memento) → 상태 복원

상호작용 다이어그램

sequenceDiagram
    participant C as Client
    participant CT as Caretaker
    participant O as Originator
    participant M as Memento
    
    C->>CT: 상태 저장 요청
    CT->>O: createMemento()
    O->>M: new Memento(state)
    M-->>O: memento
    O-->>CT: memento
    CT-->>C: 저장 완료
    
    Note over C,M: 시간 경과 후
    
    C->>CT: 상태 복원 요청
    CT->>O: restore(memento)
    O->>M: getState()
    M-->>O: state
    O-->>CT: 복원 완료
    CT-->>C: 복원 완료

Part 2: 구조 및 아키텍처

구조 및 아키텍처

필수 구성요소

1. Originator (원조자)
2. Memento (메멘토)
3. Caretaker (관리자)

선택 구성요소

1. Client (클라이언트)

아키텍처 다이어그램

classDiagram
    class Originator {
        -state: Object
        +createMemento(): Memento
        +restore(memento: Memento): void
        +setState(state: Object): void
        +getState(): Object
    }
    
    class Memento {
        -state: Object
        +Memento(state: Object)
        <<friend>> +getState(): Object
    }
    
    class Caretaker {
        -mementos: List~Memento~
        +addMemento(memento: Memento): void
        +getMemento(index: int): Memento
        +undo(): void
        +redo(): void
    }
    
    class Client {
        +main(): void
    }
    
    Originator --> Memento : creates
    Caretaker --> Memento : stores
    Client --> Originator : uses
    Client --> Caretaker : uses
    
    note for Memento "불변 객체\n좁은/넓은 인터페이스"
    note for Originator "Memento의 모든 내용 접근 가능"
    note for Caretaker "Memento 내용 접근 불가"

구성요소 간 관계

의존 관계
통신 흐름
  1. 저장 흐름: Client → Caretaker → Originator → Memento
  2. 복원 흐름: Client → Caretaker → Originator ← Memento

Part 3: 구현 및 활용

구현 기법

1. 중첩 클래스 (Nested Class) 기법

정의: Memento 를 Originator 의 내부 클래스로 구현하는 방법

구성:

목적: 캡슐화를 강화하고 Memento 의 내부 상태를 완전히 숨김

실제 예시:

 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
// 시나리오: 텍스트 에디터의 문서 상태 관리
public class TextEditor {
    private String content;
    private String formatting;
    
    public Memento createMemento() {
        return new Memento(content, formatting);
    }
    
    public void restore(Memento memento) {
        this.content = memento.getContent();
        this.formatting = memento.getFormatting();
    }
    
    // 중첩된 Memento 클래스
    public static class Memento {
        private final String content;
        private final String formatting;
        
        private Memento(String content, String formatting) {
            this.content = content;
            this.formatting = formatting;
        }
        
        private String getContent() { return content; }
        private String getFormatting() { return formatting; }
    }
}

2. 직렬화 (Serialization) 기법

정의: 객체의 상태를 바이트 스트림으로 변환하여 저장하는 방법

구성:

목적: 범용적인 상태 저장 메커니즘 제공

실제 예시:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 시나리오: 게임 캐릭터 상태 저장
public class GameCharacter implements Serializable {
    private String name;
    private int level;
    private Map<String, Integer> attributes;
    
    public SerializedMemento createMemento() throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(this);
        return new SerializedMemento(baos.toByteArray());
    }
    
    public void restore(SerializedMemento memento) throws IOException, ClassNotFoundException {
        ByteArrayInputStream bais = new ByteArrayInputStream(memento.getData());
        ObjectInputStream ois = new ObjectInputStream(bais);
        GameCharacter saved = (GameCharacter) ois.readObject();
        
        this.name = saved.name;
        this.level = saved.level;
        this.attributes = saved.attributes;
    }
}

3. 패키지 가시성 (Package Visibility) 기법

정의: 같은 패키지 내에서만 접근 가능한 가시성을 활용하는 방법

구성:

목적: 중첩 클래스 없이 제어된 접근 제공

실제 예시:

 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
// 시나리오: 계산기 상태 관리
package calculator;

public class Calculator {
    private double result;
    private String lastOperation;
    
    public CalculatorMemento createMemento() {
        return new CalculatorMemento(result, lastOperation);
    }
    
    public void restore(CalculatorMemento memento) {
        this.result = memento.result;
        this.lastOperation = memento.lastOperation;
    }
}

// 같은 패키지의 Memento 클래스
class CalculatorMemento {
    final double result;           // package-private
    final String lastOperation;    // package-private
    
    CalculatorMemento(double result, String lastOperation) {
        this.result = result;
        this.lastOperation = lastOperation;
    }
}

4. 프록시 (Proxy) 기법

정의: 프록시 객체를 통해 원본 객체의 상태를 저장하고 복원하는 방법

구성:

목적: 유연한 상태 관리와 접근 제어

실제 예시:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// 시나리오: 복잡한 그래픽 객체의 상태 관리
public class GraphicsObjectProxy {
    private GraphicsObject target;
    
    public GraphicsMemento createMemento() {
        // 선택적으로 일부 상태만 저장
        return new GraphicsMemento(
            target.getPosition(),
            target.getColor(),
            // 복잡한 렌더링 정보는 제외
        );
    }
    
    public void restore(GraphicsMemento memento) {
        target.setPosition(memento.getPosition());
        target.setColor(memento.getColor());
        // 필요시 추가 복원 로직
        target.invalidateCache();
    }
}

장점과 단점

구분항목설명
✅ 장점캡슐화 보존객체의 내부 상태를 외부에 노출하지 않으면서 상태 관리
단순한 복원복잡한 역연산 없이 저장된 상태로 직접 복원
높은 응집도상태 관리 책임이 각 구성요소에 명확히 분리
안전한 실행 취소실행 취소 기능을 안전하고 신뢰성 있게 구현
독립적 관리Caretaker 가 여러 Memento 를 독립적으로 관리
⚠ 단점메모리 오버헤드많은 Memento 저장 시 메모리 사용량 증가
성능 비용상태 저장과 복원 과정에서 성능 오버헤드 발생
구현 복잡성중첩 클래스나 특별한 접근 제어 메커니즘 필요
단일 객체 제한한 번에 하나의 객체 상태만 처리 가능
유지보수 비용Originator 변경 시 Memento 도 함께 수정 필요

도전 과제

1. 메모리 관리 최적화

설명: 대량의 Memento 객체로 인한 메모리 부족 문제 해결책:

2. 대용량 객체 상태 관리

설명: 복잡하고 큰 객체의 상태 저장 시 성능 저하 해결책:

3. 동시성 제어

설명: 멀티스레드 환경에서의 상태 일관성 문제 해결책:

4. 복잡한 객체 그래프 처리

설명: 상호 참조하는 객체들의 상태 저장 복잡성 해결책:


Part 4: 실무 적용 및 최신 동향

분류에 따른 종류 및 유형

분류 기준유형설명특징
저장 방식완전 스냅샷객체의 전체 상태를 저장간단하지만 메모리 사용량 많음
차등 스냅샷이전 상태와의 차이점만 저장메모리 효율적이지만 복원 복잡
압축 스냅샷압축된 형태로 상태 저장저장 공간 절약, CPU 사용량 증가
구현 방법중첩 클래스 방식Memento 를 내부 클래스로 구현강한 캡슐화, 언어 종속적
직렬화 방식객체 직렬화로 상태 저장범용적, 성능 오버헤드
복사 방식깊은 복사로 상태 저장단순하지만 복사 비용 높음
관리 정책LIFO 스택 방식스택으로 Memento 관리실행 취소에 적합
링크드 리스트 방식연결 리스트로 관리임의 접근 가능
순환 버퍼 방식고정 크기 버퍼로 관리메모리 사용량 제한
적용 범위단일 객체형하나의 객체만 처리전통적인 Memento 패턴
복합 객체형여러 객체를 동시 처리트랜잭션 시스템에 적용
계층적 객체형객체 계층 구조 전체 처리복잡한 도메인 모델에 적용

실무 적용 예시

분야애플리케이션적용 사례구현 방식
텍스트 편집Microsoft Word문서 편집 실행 취소차등 스냅샷 + 압축
IDEIntelliJ IDEA코드 리팩토링 되돌리기파일 단위 메멘토
게임RPG 게임세이브/로드 시스템직렬화 기반 저장
그래픽 편집Adobe Photoshop레이어 상태 관리타일 기반 부분 저장
데이터베이스RDBMS트랜잭션 롤백로그 기반 메멘토
웹 브라우저Chrome/Firefox뒤로 가기 기능페이지 상태 캐싱
CAD 소프트웨어AutoCAD설계 변경 이력 관리벡터 기반 차등 저장
금융 시스템거래 시스템주문 취소 및 복구이벤트 소싱 패턴

활용 사례

시나리오: 협업 문서 편집 시스템

시스템 구성
시스템 구성 다이어그램
graph TB
    subgraph "Client Layer"
        UI[Web Editor UI]
        CM[Client Memento Manager]
    end
    
    subgraph "Application Layer"
        API[REST API Gateway]
        WS[WebSocket Server]
        MM[Memento Manager Service]
    end
    
    subgraph "Storage Layer"
        RC[Redis Cache]
        DB[(MongoDB)]
        FS[File Storage]
    end
    
    UI --> CM
    CM --> API
    API --> MM
    MM --> RC
    MM --> DB
    WS --> UI
    
    classDef client fill:#e1f5fe
    classDef app fill:#f3e5f5
    classDef storage fill:#e8f5e8
    
    class UI,CM client
    class API,WS,MM app
    class RC,DB,FS storage
활용 사례 Workflow
sequenceDiagram
    participant U as User
    participant E as Editor
    participant MM as MementoManager
    participant C as Cache
    participant DB as Database
    
    U->>E: 문서 편집 시작
    E->>MM: createCheckpoint()
    MM->>C: 현재 상태 저장
    
    Note over U,DB: 편집 작업 수행
    U->>E: 텍스트 입력/수정
    E->>MM: autoSave() 호출
    MM->>C: 자동 저장
    MM->>DB: 주기적 영구 저장
    
    Note over U,DB: 실행 취소 요청
    U->>E: Ctrl+Z (Undo)
    E->>MM: undo()
    MM->>C: 이전 Memento 조회
    C-->>MM: Memento 반환
    MM-->>E: 이전 상태 복원 
    E-->>U: 문서 상태 업데이트
    Note over U,DB: 협업자 변경사항 동기화 
    E->>MM: mergeChanges() 
    MM->>C: 충돌 해결 후 저장 
    MM->>DB: 최종 상태 영구 저장
메멘토 패턴의 역할
  1. 문서 상태 관리: 각 편집 단계별로 문서 상태를 Memento 로 저장
  2. 실시간 협업 지원: 여러 사용자의 변경사항을 독립적인 Memento 로 관리
  3. 충돌 해결: 동시 편집 시 각 사용자의 상태를 별도 Memento 로 보관하여 병합
  4. 자동 저장: 주기적으로 Memento 생성하여 데이터 손실 방지

실무에서 효과적으로 적용하기 위한 고려사항 및 주의할 점

구분고려사항설명권장사항
설계상태 범위 정의저장할 상태의 범위를 명확히 정의핵심 상태만 선별하여 저장, 파생 가능한 데이터는 제외
성능메모리 사용량 관리Memento 누적으로 인한 메모리 부족LRU 캐시 정책 적용, 최대 보관 개수 제한 설정
동시성스레드 안전성 확보멀티스레드 환경에서의 상태 일관성불변 Memento 사용, ConcurrentHashMap 활용
확장성상태 진화 대응시간에 따른 객체 구조 변화버전 관리 메커니즘 도입, 하위 호환성 보장
복구손상된 Memento 처리저장된 상태 정보의 무결성체크섬 검증, 다중 백업 전략 적용
보안민감 정보 보호상태 저장 시 보안 고려민감 데이터 암호화, 접근 권한 제어
테스트상태 복원 검증복원된 상태의 정확성 확인자동화된 상태 비교 테스트, 무결성 검사
모니터링성능 메트릭 수집패턴 사용에 따른 성능 영향메모리 사용량, 복원 시간 모니터링

최적화하기 위한 고려사항 및 주의할 점

구분최적화 방안설명권장사항
메모리압축 알고리즘 적용상태 데이터를 압축하여 저장 공간 절약GZIP, LZ4 등 빠른 압축 알고리즘 사용
I/O지연 로딩 구현필요할 때만 Memento 내용을 메모리에 로드Lazy Loading 패턴과 결합, 프록시 객체 활용
직렬화효율적 직렬화 방식빠른 직렬화/역직렬화 라이브러리 사용Kryo, FlatBuffers, Protocol Buffers 활용
캐싱다층 캐싱 전략자주 사용되는 Memento 는 빠른 캐시에 보관L1(메모리) + L2(SSD) + L3(HDD) 계층 구조
배치 처리일괄 저장 방식여러 Memento 를 한 번에 처리배치 크기 최적화, 비동기 처리 도입
가비지 컬렉션메모리 풀 사용객체 생성/소멸 비용 최소화객체 풀 패턴 적용, 재사용 가능한 Memento 객체
네트워크차등 동기화변경된 부분만 네트워크로 전송Delta Sync, Binary Diff 알고리즘 활용
인덱싱빠른 검색 지원Memento 조회 속도 향상해시 인덱스, B-Tree 인덱스 구조 활용

기타 사항

관련 패턴과의 조합

Command 패턴과의 결합
Observer 패턴과의 결합
Prototype 패턴과의 비교

현대적 구현 고려사항

함수형 프로그래밍과의 조화
마이크로서비스 아키텍처에서의 적용

2025 년 기준 최신 동향

주제항목설명
클라우드 네이티브서버리스 MementoAWS Lambda, Azure Functions 에서 상태 관리 최적화
AI/ML 통합지능형 압축AI 기반 상태 압축으로 저장 공간 90% 절약
실시간 협업CRDT 통합Conflict-free Replicated Data Type 과 결합한 분산 Memento
성능 최적화WASM 활용WebAssembly 로 브라우저에서 고성능 상태 처리
보안 강화동형 암호화암호화된 상태에서도 연산 가능한 Memento 구현

주제와 관련하여 주목할 내용

주제항목설명
양자 컴퓨팅양자 상태 저장양자 중첩 상태를 고전적 Memento 로 근사 저장
블록체인불변 이력 관리블록체인의 불변성을 활용한 Memento 저장
엣지 컴퓨팅분산 캐싱CDN 엣지에서 Memento 캐싱으로 응답 속도 향상
그린 IT에너지 효율저전력 메모리를 활용한 친환경 상태 저장
개인정보보호차등 프라이버시개인정보를 포함한 상태 저장 시 프라이버시 보장

앞으로의 전망

주제항목설명
자동화AI 기반 최적화머신러닝으로 최적의 Memento 저장 시점 예측
표준화패턴 표준 API언어별 표준 Memento API 제정 추진
확장성무한 확장형클라우드 스토리지와 결합한 무제한 상태 저장
융합 기술디지털 트윈**IoT 와 결합하여 물리 세계 상태의 디지털 Memento
새로운 패러다임시공간 Memento4 차원 (시간 포함) 상태 관리 시스템

하위 주제로 분류한 추가 학습 내용

카테고리주제설명
고급 구현Persistent Data Structures함수형 프로그래밍의 영속 자료구조 활용
성능 최적화Copy-on-Write 메커니즘지연 복사를 통한 메모리 효율성
분산 시스템Vector Clocks분산 환경에서의 인과관계 기반 상태 순서
데이터베이스MVCC (Multi-Version Concurrency Control)데이터베이스의 다중 버전 동시성 제어
웹 기술Browser History API웹 브라우저의 상태 관리 메커니즘

관련 분야와 함께 알아야 할 내용

관련 분야주제설명
운영체제Process Checkpoint/Restore프로세스 상태 저장 및 복원 기술
데이터베이스Transaction Log트랜잭션 로그를 통한 상태 복구
게임 개발Save Game Systems게임 상태 저장 시스템 설계
분산 컴퓨팅Consensus Algorithms분산 시스템에서의 상태 합의 알고리즘
버전 관리Git InternalsGit 의 스냅샷 기반 버전 관리 시스템
컴파일러Static Single Assignment컴파일러의 중간 표현에서 상태 관리

용어 정리

용어설명
토큰 패턴 (Token Pattern)메멘토 패턴의 다른 이름으로, 상태를 토큰 형태로 저장한다는 의미
투명한 객체 (Opaque Object)내부 구조를 알 수 없고 수정할 수 없는 객체
좁은 인터페이스 (Narrow Interface)Caretaker 가 접근할 수 있는 제한된 메서드 집합
넓은 인터페이스 (Wide Interface)Originator 가 접근할 수 있는 모든 메서드 집합
차등 백업 (Differential Backup)이전 상태와의 차이점만 저장하는 백업 방식
구조적 공유 (Structural Sharing)변경되지 않은 부분을 여러 버전에서 공유하는 기법
이벤트 소싱 (Event Sourcing)상태 변경을 이벤트로 저장하여 현재 상태를 재구성하는 패턴
CRDT (Conflict-free Replicated Data Type)분산 환경에서 충돌 없이 복제 가능한 데이터 타입

참고 및 출처