맨위로가기

메멘토 패턴

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

메멘토 패턴은 객체의 내부 상태를 캡처하여 나중에 복원할 수 있도록 하는 디자인 패턴이다. 이 패턴은 Originator, Memento, Caretaker의 세 가지 주요 구성 요소로 이루어진다. Originator는 내부 상태를 가지며, Memento 객체를 생성하여 현재 상태를 저장하고, Memento 객체를 사용하여 상태를 복원한다. Caretaker는 Memento 객체를 저장하고 관리하며, Originator의 상태를 저장하고 복원하는 역할을 한다. 메멘토 패턴은 실행 취소(undo) 기능 구현, 객체의 상태를 캡슐화하여 외부에서 직접 접근을 막는 데 사용되며, 다양한 프로그래밍 언어(Ruby, Java, C#, Python, Javascript 등)에서 구현될 수 있다.

더 읽어볼만한 페이지

  • 소프트웨어 디자인 패턴 - 모델-뷰-컨트롤러
    모델-뷰-컨트롤러(MVC)는 소프트웨어 디자인 패턴으로, 응용 프로그램을 모델, 뷰, 컨트롤러 세 가지 요소로 분리하여 개발하며, 사용자 인터페이스 개발에서 데이터, 표현 방식, 사용자 입력 처리를 분리해 유지보수성과 확장성을 높이는 데 기여한다.
  • 소프트웨어 디자인 패턴 - 스케줄링 (컴퓨팅)
    스케줄링은 운영 체제가 시스템의 목적과 환경에 맞춰 작업을 관리하는 기법으로, 장기, 중기, 단기 스케줄러를 통해 프로세스를 선택하며, CPU 사용률, 처리량 등을 기준으로 평가하고, FCFS, SJF, RR 등의 알고리즘을 사용한다.
메멘토 패턴
개요
이름메멘토 패턴
유형행위 디자인 패턴
의도객체의 내부 상태를 캡처하고 외부화하여 나중에 객체를 해당 상태로 복원할 수 있도록 한다. 캡처는 객체 자체에 의해 수행되므로 객체의 캡슐화가 유지된다.
별칭토큰
문제객체의 전체 상태(전체 데이터)는 외부에서 사용할 수 없지만 객체의 캡슐화는 손상시키지 않고 저장해야 한다.
해결책객체(originator)는 자신의 내부 상태의 표현을 생성하고 이를 멘토(memento)에 저장한다. 나중에 객체를 동일한 상태로 복원할 수 있다.
메멘토 패턴 UML 클래스 다이어그램
메멘토 패턴 UML 클래스 다이어그램
참여자 및 협력Originator (원작자): 내부 상태를 알고 상태의 멘토를 생성하고 멘토에서 상태를 복원한다.
Memento (메멘토): 원작자의 내부 상태를 저장한다.
Caretaker (관리자): 멘토를 보관한다.
결과내부 상태는 외부에서 사용할 수 없기 때문에 객체의 캡슐화가 유지된다.
Originator에 따라 멘토에 저장할 상태를 정의할 수 있다.
단점상태가 멘토에 복사되므로 리소스가 많이 소모될 수 있다.
사용 예명령 디자인 패턴
시리얼화
트랜잭션
구현Memento는 Originator가 사용해야 한다.
프로그래밍 언어가 중첩 클래스를 지원하는 경우 Memento를 Originator 내부에 정의할 수 있다.
그렇지 않으면 Originator만 Memento의 데이터에 액세스할 수 있는지 확인해야 한다.
예시아래의 C++ 예시에서 `originator` 클래스는 자체 상태를 `memento` 클래스에 저장하고 `memento` 클래스에서 복원하는 방법을 안다.
관리자 클래스는 멘토 객체를 책임진다. 멘토 객체에 저장된 원작자의 상태를 조작/검사하지 않는다.
C++ 예시C++ 예시
Java 예시Java 예시
C# 예시C# 예시
PHP 예시PHP 예시
Python 예시Python 예시

2. 구조

메멘토 디자인 패턴은 Originator(오리지네이터), Memento (메멘토), Caretaker (케어테이커) 세 가지 주요 구성 요소로 이루어진다.


  • '''Originator(오리지네이터)''': 자신의 상태를 저장하고 복원한다. Memento 객체를 생성 및 이용하여 상태를 관리한다.
  • '''Memento (메멘토)''': Originator 객체의 내부 상태를 저장한다. Originator 객체만 접근 가능하다.
  • '''Caretaker (케어테이커)''': 메멘토 객체를 관리한다. Originator 객체에 메멘토 객체를 요청 및 전달하여 상태 복원을 요청한다.




위 UML 클래스 다이어그램에서, `Caretaker` 클래스는 오리지네이터(`Originator`)의 내부 상태를 저장(`createMemento()`)하고 복구(`restore(memento)`)하기 위해 `Originator` 클래스를 참조한다.[1] `Originator` 클래스는 오리지네이터의 현재 내부 상태를 저장하는 `Memento` 객체를 생성 및 반환하고(`createMemento()`), `Memento` 객체로 전달된 상태를 복구한다(`restore(memento)`).[1]

2. 1. Originator (오리지네이터)

Originator(오리지네이터)는 자신의 상태를 저장하고 복원하는 객체이다. Memento 객체를 생성하여 현재 상태를 저장하고, Memento 객체를 이용하여 이전 상태로 복원한다.[3]

Originator는 다음 작업을 수행한다.

  • 내부 상태를 Memento 객체에 저장한다.
  • Memento 객체로부터 이전 상태를 복원한다.


Memento는 Originator만 접근할 수 있다. 이를 통해 캡슐화를 유지하면서 객체의 내부 상태를 저장하고 복원할 수 있다.

한국 게임 개발에서는 플레이어 캐릭터의 상태(레벨, 경험치, 아이템 등)를 저장하는 데 Originator 클래스를 활용할 수 있다. 예를 들어, 플레이어가 게임을 종료하거나 특정 시점에 게임을 저장할 때 캐릭터 상태를 Memento 객체에 저장하고, 나중에 게임을 다시 시작하거나 저장된 지점에서 불러올 때 Memento 객체로부터 캐릭터 상태를 복원할 수 있다.

2. 2. Memento (메멘토)

메멘토는 오리지네이터(Originator) 객체의 내부 상태를 저장하는 객체이다.[3] Originator 객체만이 Memento 객체에 접근하여 상태를 저장하고 복원할 수 있다. Memento는 일반적으로 불변 객체(immutable object)로 구현된다. 예를 들어, Java에서는 String, C#에서는 `readonly` 키워드를 활용하여 불변 객체로 구현할 수 있다.

메멘토 패턴의 핵심은 캡슐화를 유지하면서 객체의 내부 상태를 저장하고 복원하는 것이다. 클라이언트(Caretaker)는 Originator에게 Memento 생성을 요청하고, 나중에 이를 Originator에게 다시 전달하여 이전 상태로 복원하도록 요청한다.[3]

다음은 메멘토 패턴의 "undo" 사용을 보여주는 Java 코드 예시이다.

```java

import java.util.List;

import java.util.ArrayList;

class Originator {

private String state;

public void set(String state) {

this.state = state;

System.out.println("Originator: Setting state to " + state);

}

public Memento saveToMemento() {

System.out.println("Originator: Saving to Memento.");

return new Memento(this.state);

}

public void restoreFromMemento(Memento memento) {

this.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;

}

private 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");

savedStates.add(originator.saveToMemento());

originator.set("State4");

originator.restoreFromMemento(savedStates.get(1));

}

}

```

이 예제는 String (Java에서 불변 객체)을 상태로 사용한다. 실제 시나리오에서는 상태가 거의 항상 객체이며, 이 경우 상태 복사가 필요하다.

한국의 워드프로세서 개발에서는 문서의 특정 시점 내용을 Memento 객체에 저장하여 사용자가 이전 편집 상태로 되돌아갈 수 있도록 구현할 수 있다.

2. 3. Caretaker (케어테이커)

Caretaker(케어테이커)는 메멘토 객체를 관리하는 역할을 한다. Originator(오리지네이터) 객체에 메멘토 객체를 요청하여 저장하고, 저장된 메멘토 객체를 Originator 객체에 전달하여 상태 복원을 요청하는 역할을 수행한다.[3] Caretaker는 메멘토 객체의 내부 구조를 알지 못하며, 접근할 수도 없다.

예를 들어, 한국의 웹 브라우저 개발에서 Caretaker는 방문 기록을 관리하고, 각 페이지의 상태를 메멘토에 저장하여 "뒤로 가기" 기능을 구현할 수 있다.

2. 4. UML 클래스 및 시퀀스 다이어그램



위 UML 클래스 다이어그램에서, `Caretaker` 클래스는 오리지네이터(`Originator`)의 내부 상태를 저장(`createMemento()`)하고 복구(`restore(memento)`)하기 위해 `Originator` 클래스를 참조한다.

`Originator` 클래스는 다음을 구현한다.

(1) 오리지네이터의 현재 내부 상태를 저장하는 `Memento` 객체를 생성하고 반환하는 `createMemento()`

(2) `Memento` 객체로 전달된 상태를 복구하는 `restore(memento)`

UML 시퀀스 다이어그램은 런타임 상호작용을 보여준다.

(1) 오리지네이터의 내부 상태 저장: `Caretaker` 객체는 `Originator` 객체의 `createMemento()`를 호출하여 `Memento` 객체를 생성하고 현재 내부 상태(`setState()`)를 저장한 뒤, `Caretaker`에 `Memento`를 반환한다.

(2) 오리지네이터의 내부 상태 복구: `Caretaker`는 `Originator` 객체의 `restore(memento)`를 호출하고 복구할 상태를 저장하고 있는 `Memento` 객체를 가져온다(`getState()`).[1]

3. 구현 방법

메멘토 패턴을 구현하는 방법은 여러 가지가 있다.

자바를 사용한 예시에서는 String을 상태로 사용하는데, 이는 Java에서 String이 불변 객체이기 때문이다. 실제 상황에서는 상태가 객체인 경우가 대부분이므로, 상태를 복사해야 한다.

내부 클래스를 사용한 구현은 취약점을 가질 수 있다. 이 방식은 오리지네이터(Originator)가 하나 이상일 때 적용하는 것이 더 좋다.

메멘토 패턴을 구현하는 주요 방법은 다음과 같다.


  • '''직렬화''': 객체의 상태를 바이트 스트림으로 변환하여 저장하고, 필요할 때 다시 객체로 복원한다.
  • '''동일한 패키지에 선언된 클래스''': 클래스 간의 접근을 제어하여 캡슐화를 유지한다.
  • '''프록시''': 객체에 대한 접근을 제어하는 프록시를 통해 저장/복구 작업을 수행한다.


다음은 객체의 변경 사항을 취소하기 위해 메멘토 객체를 사용하는 C# 코드 예시이다.

```csharp

public class OriginalObject

{

public string String1 { get; set; }

public string String2 { get; set; }

public OriginalObject(string str1, string str2)

{

this.String1 = str1;

this.String2 = str2;

}

public void SetMemento(Memento memento)

{

this.String1 = memento.string1;

this.String2 = memento.string2;

}

public Memento CreateMemento()

{

return new Memento(this.String1, this.String2);

}

}

//Memento object

public class Memento

{

public readonly string string1;

public readonly string string2;

public Memento(string str1, string str2)

{

this.string1 = str1;

this.string2 = str2;

}

}

//CareTaker Object

public class CareTaker

{

public Memento Memento { get; set; }

}

//Client

class Program

{

static void Main(string[] args)

{

// Create Originator object which container first state of "First" and "One".

// The Memento will remember these value.

OriginalObject original = new OriginalObject("First", "One");

// Create first State and store to caretaker

Memento firstMemento = original.CreateMemento();

CareTaker caretaker = new CareTaker();

caretaker.Memento = firstMemento;

// Change into second state; "Second" and "Two".

original.String1 = "Second";

original.String2 = "Two";

// Retrieve back first State

original.SetMemento(caretaker.Memento);

}

}

```

다음은 파이썬(Python)을 사용한 "실행 취소" 예시이다.

```python

class Memento(object):

def __init__(self, state):

self._state = state

def get_saved_state(self):

return self._state

class Originator(object):

_state = ""

def set(self, state):

print("Originator: Setting state to", state)

self._state = state

def save_to_memento(self):

print("Originator: Saving to Memento.")

return Memento(self._state)

def restore_from_memento(self, memento):

self._state = memento.get_saved_state()

print("Originator: State after restoring from Memento:", self._state)

saved_states = []

originator = Originator()

originator.set("State1")

originator.set("State2")

saved_states.append(originator.save_to_memento())

originator.set("State3")

saved_states.append(originator.save_to_memento())

originator.set("State4")

originator.restore_from_memento(saved_states[0])

3. 1. 직렬화(Serialization)

객체의 상태를 바이트 스트림으로 변환하여 저장하고, 다시 객체로 복원하는 것을 직렬화라고 한다. Java, C# 등 많은 프로그래밍 언어에서 직렬화 기능을 제공한다. 객체의 상태를 파일이나 네트워크를 통해 저장하고 전송하는 데 유용하다.

3. 2. 내부 클래스(Inner Class)

다음은 자바로 메멘토 패턴의 "실행 취소" 기능을 구현한 예시이다.



import java.util.*;

class Originator {

private String state;

/* 메모리를 소비하는 다수의 private 데이터로 상태와 관계없는 것은 저장하지 않아야 한다.

  • memento는 작은 객체여야 한다 */


public void set(String state) {

System.out.println("Originator: Setting state to "+state);

this.state = state;

}

public Object saveToMemento() {

System.out.println("Originator: Saving to Memento.");

return new Memento(state);

}

public void restoreFromMemento(Object m) {

if (m instanceof Memento) {

Memento memento = (Memento)m;

state = memento.getSavedState();

System.out.println("Originator: State after restoring from Memento: "+state);

}

}

private static class Memento {

private String state;

public Memento(String stateToSave) { state = stateToSave; }

public String getSavedState() { return state; }

}

}

class Caretaker {

private List savedStates = new ArrayList();

public void addMemento(Object m) { savedStates.add(m); }

public Object getMemento(int index) { return savedStates.get(index); }

}

class MementoExample {

public static void main(String[] args) {

Caretaker caretaker = new Caretaker();

Originator originator = new Originator();

originator.set("State1");

originator.set("State2");

caretaker.addMemento( originator.saveToMemento() );

originator.set("State3");

caretaker.addMemento( originator.saveToMemento() );

originator.set("State4");

originator.restoreFromMemento( caretaker.getMemento(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

자바에서 Originator 클래스 내부에 Memento 클래스를 정의하면 캡슐화를 강화할 수 있다. Memento 클래스는 Originator 클래스에서만 접근 가능하므로, 외부로부터 상태 접근을 제한할 수 있다. 단, 내부 클래스는 외부 클래스와 강하게 결합되므로, Originator가 여러 개일 때는 적용하기 어렵다.

4. 예시

메멘토 패턴은 객체의 내부 상태를 캡슐화하여 저장하고, 필요에 따라 이전 상태로 복원할 수 있도록 하는 디자인 패턴이다. 다양한 프로그래밍 언어를 통해 메멘토 패턴의 구현 예시를 살펴보자.

메멘토 패턴은 주로 다음과 같은 세 가지 주요 방법으로 구현될 수 있다.[1]

1. 직렬화: 객체의 상태를 직렬화하여 저장하고 복원한다.

2. 동일한 패키지에 선언된 클래스: 같은 패키지 내의 클래스 간 접근을 활용하여 상태를 저장하고 복원한다.

3. 프록시: 객체에 대한 접근을 제어하는 프록시를 통해 상태 저장 및 복원 작업을 수행한다.

C# 예시에서는 객체에서 발생한 변경 사항을 취소하기 위해 메멘토 객체가 사용되는 방식을 보여준다. (C# 코드 예시는 하위 섹션 "C# 예시"에서 확인할 수 있다.)

파이썬으로 작성된 메멘토 패턴 예시는 다음과 같다. (파이썬 코드 예시는 하위 섹션 "Python 예시"에서 확인할 수 있다.)

4. 1. Java 예시

다음은 자바 프로그램으로, 메멘토 패턴을 "실행 취소" 기능에 사용한 예시이다.



import java.util.List;

import java.util.ArrayList;

class Originator {

private String state;

// 이 클래스는 메멘토에 저장된 상태의 일부가 아닌 추가 데이터를 포함할 수 있다.

public void set(String state) {

this.state = state;

System.out.println("Originator: Setting state to " + state);

}

public Memento saveToMemento() {

System.out.println("Originator: Saving to Memento.");

return new Memento(this.state);

}

public void restoreFromMemento(Memento memento) {

this.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;

}

// 외부 클래스에서만 접근 가능

private 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");

// 여러 개의 메멘토를 요청하고, 되돌릴 메멘토를 선택할 수 있다.

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



이 예제는 Java에서 불변 객체인 문자열(String)을 상태로 사용한다. 실제 시나리오에서는 상태가 거의 항상 가변 객체일 것이며, 이 경우 상태의 복사본을 만들어야 한다.[1]

4. 2. C# 예시

이 예제는 C#을 사용하여 실행 취소 기능을 구현한 것이다.

```csharp

class Memento

{

private readonly string savedState;

private Memento(string stateToSave)

{

savedState = stateToSave;

}

public class Originator

{

private string state;

// 이 클래스는 메멘토에 저장된 상태의 일부가 아닌 추가 데이터도 포함할 수 있습니다.

public void Set(string state)

{

Console.WriteLine("Originator: 상태를 " + state + "로 설정");

this.state = state;

}

public Memento SaveToMemento()

{

Console.WriteLine("Originator: 메멘토에 저장");

return new Memento(state);

}

public void RestoreFromMemento(Memento memento)

{

state = memento.savedState;

Console.WriteLine("Originator: 메멘토에서 복원한 후의 상태: " + state);

}

}

}

class Caretaker

{

static void Main(string[] args)

{

var savedStates = new List();

var originator = new Memento.Originator();

originator.Set("State1");

originator.Set("State2");

savedStates.Add(originator.SaveToMemento());

originator.Set("State3");

// 여러 메멘토를 요청하고 롤백할 대상을 선택할 수 있습니다.

savedStates.Add(originator.SaveToMemento());

originator.Set("State4");

originator.RestoreFromMemento(savedStates[1]);

}

}

4. 3. Python 예시

python

# 메멘토 패턴 예시

class Originator:

_state = ""

def set(self, state: str) -> None:

print(f"Originator: 상태를 {state}로 설정")

self._state = state

def save_to_memento(self) -> "Memento":

return self.Memento(self._state)

def restore_from_memento(self, m: "Memento") -> None:

self._state = m.get_saved_state()

print(f"Originator: 메멘토에서 복원한 후의 상태: {self._state}")

class Memento:

def __init__(self, state):

self._state = state

def get_saved_state(self):

return self._state

saved_states = []

originator = Originator()

originator.set("State1")

originator.set("State2")

saved_states.append(originator.save_to_memento())

originator.set("State3")

saved_states.append(originator.save_to_memento())

originator.set("State4")

originator.restore_from_memento(saved_states[1])

4. 4. Javascript 예시

javascript

// 메멘토 패턴은 객체의 상태를 저장하고 복원하는 데 사용된다.

// 메멘토는 객체의 상태를 스냅샷으로 캡처한 것이다.

var Memento = { // 네임스페이스: Memento

savedState: null, // 저장된 객체의 상태

save: function(state) { // 객체의 상태를 저장한다.

this.savedState = state;

},

restore: function() { // 객체의 상태를 복원한다.

return this.savedState;

}

};

// Originator는 메멘토를 생성하는 객체이다.

// 메멘토 내에 상태를 저장하는 메서드를 정의한다.

var Originator = { // 네임스페이스: Originator

state: null, // 저장할 상태

// 초기 상태가 null인 새로운 Originator를 생성한다.

createMemento: function() {

return {

state: this.state // 상태가 메멘토로 복사된다.

};

},

setMemento: function(memento) { // 메멘토로부터 Originator의 상태를 설정한다.

this.state = memento.state;

}

};

// Caretaker는 객체의 메멘토를 저장하고

// 메멘토를 검색하는 연산을 제공한다.

var Caretaker = { // 네임스페이스: Caretaker

mementos: [], // 객체의 메멘토

addMemento: function(memento) { // 컬렉션에 메멘토를 추가한다.

this.mementos.push(memento);

},

getMemento: function(index) { // 컬렉션에서 메멘토를 가져온다.

return this.mementos[index];

}

};

var action_step = "Foo"; // 실행될 동작/저장될 객체의 상태

var action_step_2 = "Bar"; // 실행될 동작/저장될 객체의 상태

// 초기 상태 설정

Originator.state = action_step;

Caretaker.addMemento(Originator.createMemento()); // 상태를 히스토리에 저장

console.log("Initial State: " + Originator.state); // Foo

// 상태 변경

Originator.state = action_step_2;

Caretaker.addMemento(Originator.createMemento()); // 상태를 히스토리에 저장

console.log("State After Change: " + Originator.state); // Bar

// 첫 번째 상태 복원 - 실행 취소 (undo)

Originator.setMemento(Caretaker.getMemento(0));

console.log("State After Undo: " + Originator.state); // Foo

// 두 번째 상태 복원 - 다시 실행 (redo)

Originator.setMemento(Caretaker.getMemento(1));

console.log("State After Redo: " + Originator.state); // Bar

5. 활용 사례 및 장단점

메멘토 패턴은 실행 취소(Undo), 다시 실행(Redo), 게임 상태 저장, 트랜잭션 관리, 웹 브라우저 방문 기록 등 다양한 소프트웨어에서 활용된다. 객체의 내부 상태를 외부로부터 숨기면서도 상태를 저장하고 복원할 수 있도록 하여 캡슐화를 유지하고, 코드를 간결하게 유지할 수 있다는 장점이 있다. 그러나 객체의 상태를 저장하기 위해 Memento 객체를 생성하므로, 메모리 사용량이 증가할 수 있으며, 설계가 다소 복잡해질 수 있다는 단점이 있다.[2][3]

5. 1. 활용 사례

메멘토 패턴은 객체의 상태를 저장하고 나중에 복원할 수 있게 해주는 디자인 패턴으로, 다양한 소프트웨어에서 활용된다. 주요 활용 사례는 다음과 같다.

  • 실행 취소(Undo) 및 다시 실행(Redo): 워드프로세서, 그래픽 편집기 등에서 사용자의 작업 내역을 저장하고 이전 상태로 되돌리거나(`Ctrl`+`Z`) 다시 실행(`Ctrl`+`Y`)하는 기능을 구현하는 데 사용된다. 예를 들어, 사용자가 텍스트를 입력하거나 이미지를 편집하면 각 작업 단계마다 메멘토 객체를 생성하여 저장하고, 필요에 따라 이전 상태로 복원할 수 있다.

  • 게임 상태 저장: 게임에서 플레이어의 진행 상황(레벨, 아이템, 위치 등)을 저장하고 불러오는 기능을 구현하는 데 사용된다. 플레이어가 게임을 저장하면 현재 상태를 메멘토 객체로 저장하고, 나중에 게임을 다시 시작할 때 저장된 메멘토 객체를 불러와 이전 상태를 복원할 수 있다.

  • 트랜잭션(Transaction) 관리: 데이터베이스에서 데이터 변경 작업을 하나의 논리적인 단위로 묶어 처리하고, 오류 발생 시 이전 상태로 롤백하는 기능을 구현하는 데 사용된다. 예를 들어, 데이터베이스에서 여러 개의 데이터 변경 작업을 수행하는 도중 오류가 발생하면, 메멘토 패턴을 사용하여 이전 상태로 롤백하여 데이터의 무결성을 보장할 수 있다.

  • 웹 브라우저 방문 기록: 사용자가 방문한 페이지의 상태를 저장하고 "뒤로 가기" 및 "앞으로 가기" 기능을 제공한다. 웹 브라우저는 사용자가 페이지를 이동할 때마다 해당 페이지의 상태를 메멘토 객체로 저장하고, 사용자가 "뒤로 가기" 또는 "앞으로 가기" 버튼을 클릭하면 저장된 메멘토 객체를 불러와 이전 또는 다음 페이지 상태를 복원한다.

5. 2. 장점

메멘토 패턴은 객체의 내부 상태를 외부로부터 숨기면서도 상태를 저장하고 복원할 수 있도록 하여 캡슐화를 유지한다. 객체의 상태를 저장하고 복원하는 책임을 Originator 객체에 위임하여 코드를 간결하게 유지할 수 있다는 장점이 있다. 또한, Memento 객체를 불변 객체로 구현하여 외부에서 상태를 변경하는 것을 방지하여 안전성을 확보한다.[3]

5. 3. 단점

메멘토 패턴은 객체의 상태를 저장하기 위해 Memento 객체를 생성하므로, 메모리 사용량이 증가할 수 있다. 특히 Originator 객체의 상태가 크거나 복잡한 경우, 또는 상태 변화가 빈번하게 발생하는 경우 메모리 사용량이 크게 증가할 수 있다.[2] 설계 복잡성 또한 증가하는데, Originator, Memento, Caretaker 등 여러 클래스가 필요하므로, 설계가 다소 복잡해질 수 있다.[3]

6. 결론

메멘토 디자인 패턴은 객체의 상태를 저장하고 복원하는 기능을 효율적으로 구현할 수 있게 해준다. 이 패턴은 캡슐화를 유지하면서도 객체의 내부 상태에 접근하지 않고 상태를 저장하고 복원할 수 있다는 장점이 있다.[2][3] 하지만 메모리 사용량이 늘어나거나 설계가 복잡해질 수 있다는 단점도 고려해야 한다.

참조

[1] 웹사이트 The Memento design pattern - Structure and Collaboration http://w3sdesign.com[...] 2017-08-12
[2] 서적 Design Patterns: Elements of Reusable Object-Oriented Software Addison Wesley
[3] 웹인용 The GoF Design Patterns Memory - Learning Object-Oriented Design & Programming http://www.w3sdesign[...] 2019-07-23
[4] 웹인용 The Memento design pattern - Structure and Collaboration http://w3sdesign.com[...] 2017-08-12



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com