영권's

디자인 패턴(Behavioral) - Memento 본문

스터디/디자인 패턴

디자인 패턴(Behavioral) - Memento

ykkkk 2021. 8. 20. 13:41

메멘토 패턴(memento pattern)은 객체를 이전 상태로 되돌릴 수 있는 기능을 제공하는 소프트웨어 디자인 패턴이다.

 

예를 들어, 텍스트 에디터를 사용 시 필요한 텍스트를 실수로 삭제했어도 'undo(실행취소)'라는 기능을 사용하면 삭제하기 전의 상태로 텍스트를 복원할 수 있습니다.객체 지향 프로그램에서 undo 기능을 실행하려면 인스턴스가 가지고 있는 정보를 저장해 둘 필요가 있고 저장만 하지 않고 저장한 정보로부터 인스턴스를 원래의 상태로 되돌려야 합니다.

 

인스턴스를 복원하기 위해서는 인스턴스 내부의 정보를 자유롭게 액세스 할 수 있어야 하지만 원하지 않는 액세스를 허용하면 클래스 내부 구조에 의존한 코드가 프로그램의 여기저기로 흩어져서 클래스의 수정을 어렵게 만듭니다.이것을 캡슐화의 파괴라고 합니다.인스턴스의 상태를 나타내는 역할을 도입해서 캡슐화의 파괴에 빠지지 않고 저장과 복원을 실행하는 것이 Memento 패턴입니다.

Memento 패턴 클래스 다이어그램

Originator의 역할

  • Originator 역할은 자신의 현재 상태를 저장하고 싶을 때 Memento 역할을 만듭니다. 
  • 또 이전의 Memento역할을 전달받으면 그 Memento 역할을 만든 시점의 상태로 돌리는 처리를 실행합니다.

Memento의 역할

  • Memento 역할은 Originator 역할의 내부 정보를 정리합니다.
  • Originator 역할의 내부 정보를 가지고 있지만, 그 정보를 누구에게도 공개하지 않습니다.
  • 가지고 있는 두 종류의 인터페이스(API)
    • wide interface - 넓은 인터페이스(API)
      • 객체의 상태를 원래의 상태로 돌리기 위해 필요한 정보를 모두 얻을 수 있는 메서드의 집합입니다.
      • 넓은 인터페이스는 Memento 역할의 내부 상태를 모두 얻을 수 있기 때문에 이것을 사용하는 것은 Originator 역할 뿐입니다.
    • narrow Interface - 좁은 인터페이스(API)
      • Memento 역할이 제공하는 좁은 인터페이스는 외부의 Caretaker 역할에게 보여주는 것입니다.
      • 좁은 인터페이스로 할 수 있는 일에는 한계가 있고 내부 상태가 외부에 공개되는 것을 방지합니다.
  • 이 두종류의 인터페이스를 구별해서 사용하면 오브젝트의 캡슐화가 파괴되는 것을 방지할 수 있습니다.

Caretaker의 역할

  • Caretaker 역할은 현재의 Originater 역할의 상태를 저장하고 싶을 때, 그것을 Originator에게 전합니다.
  • Originator는 그것을 받아 Memento를 만들어 Caretaker에게 전달합니다.
  • Caretaker는 미래의 필요에 대비해 그 Memento를 저장합니다.
  • 그러나 Caretaker는 Memento의 좁은 인터페이스만 사용 가능하므로 Memento의 내부 정보에 엑세스 할 수 없습니다.
  • 만들어 둔 Memento 역할을 한 덩어리의 블랙박스로 통째로 저장하기만 합니다.

 

Originator과 Memento는 강하게 연결 되어 있지만, Caretaker와 Memento는 유연하게 연결되어 있습니다.

Memento는 Caretaker에게 정보은닉은 수행합니다.

 

 

Applicability

  • 객체의 이전 상태를 복원할 수 있도록 객체 상태의 스냅샷을 생성하려면 Memento 패턴을 사용할 수 있습니다.
    • Memento 패턴을 사용하여 개인 필드를 포함하여 개체 상태의 전체 복사본을 만들고 개체와 별도로 저장할 수 있습니다. 대부분의 사람들이 "Undo" 사용 사례 덕분에 이러한 패턴을 기억하지만, 트랜잭션 처리 시에도 필수적입니다(즉, 오류 시 작업을 롤백해야 하는 경우).
  • 개체의 fields/getters/setters에 대한 직접 액세스가 해당 캡슐화를 위반하는 경우 패턴을 사용합니다.
    • Memento는 개체 자체에서 해당 상태의 스냅샷을 생성하도록 합니다. 다른 개체는 스냅샷을 읽을 수 없으므로 원래 개체의 상태 데이터가 안전하고 안전합니다.

장점

  • 캡슐화를 위반하지 않고 개체 상태의 스냅샷을 생성할 수 있습니다.
  • 관리인이 원본 상태 기록을 유지 관리하도록 하여 원본 코드를 단순화할 수 있습니다.

단점

  • 클라이언트가 메모리를 너무 자주 생성하면 앱에서 RAM을 많이 사용할 수 있습니다.
  • 관리인은 사용되지 않는 메모리를 파괴할 수 있도록 원본의 라이프사이클을 추적해야 합니다.
  • PHP, Python 및 JavaScript와 같은 대부분의 동적 프로그래밍 언어에서는 메모리 내의 상태를 그대로 유지하도록 보장할 수 없습니다.

 

예제 코드

 


출처 : 

 

도서) Java언어로 배우는 디자인 패턴 입문

 

https://refactoring.guru/design-patterns/memento

 

Comments