메멘토 패턴
Memento pattern메멘토 패턴은 롤백을 통해 개체를 이전 상태로 복원하는 기능을 제공하는 소프트웨어 설계 패턴이다.
메멘토 패턴은 발신인, 관리인, 메멘토의 세 가지 객체로 구현된다.원조는 내부 상태를 가진 어떤 물체다.관리인이 원생에게 무슨 짓을 하려고 하지만, 그 변화를 되돌릴 수 있기를 원한다.관리인은 먼저 발신인에게 미멘토 물건을 요구한다.그리고 나서 그것은 그것이 하려던 모든 작전(또는 일련의 작전)을 수행한다.작업 전 상태로 롤백하려면, memento 객체를 원점자에게 반환한다.메멘토 물체 자체는 불투명한 물체(관리자가 변경할 수 없거나 변경할 수 없는 물체)이다.이 패턴을 사용할 때, 발신자가 다른 물체나 자원을 변경할 수 있는 경우 주의해야 한다. 즉, 메멘토 패턴은 단일 물체에 작용한다.
메멘토 패턴의 고전적인 예로는 유사란돔 번호 생성기(PRNG의 각 소비자는 동일한 시드(메멘토)로 PRNG(원시자)를 초기화하여 동일한 수의 시퀀스를 생산할 수 있는 관리자로서의 역할을 한다)와 유한 상태 기계에서의 상태를 들 수 있다.
개요
메멘토 디자인 패턴은 유연하고 재사용 가능한 객체 지향 소프트웨어, 즉 구현, 변경, 테스트, 재사용하기 쉬운 객체를 설계하기 위해 반복적인 설계 문제를 해결하는 방법을 설명하는 23가지 GoF 디자인 패턴 중 하나이다.메멘토 패턴은 초기 HP 제품을 위해 노아 톰슨, 데이비드 에스피리투, 드류 클링켄비어드 박사가 만들었다.
메멘토 디자인 패턴이 해결할 수 있는 문제는 무엇인가?
- 객체의 내부 상태는 객체를 나중에 이 상태로 복원할 수 있도록 외부에 저장해야 한다.
- 물체의 캡슐화를 위반해서는 안 된다.
문제는 잘 설계된 물체가 캡슐화되어 그 표현(데이터 구조)이 물체 내부에 숨겨져 물체 외부에서 접근할 수 없다는 점이다.
메멘토 디자인 패턴은 어떤 솔루션을 설명하고 있는가?
객체(원본 작성자) 자신이 책임지도록 설정
- (메모) 객체에 내부 상태 저장 및
- (메모) 개체에서 이전 상태로 복원.
미멘토를 만든 발신자만이 그것에 접근할 수 있다.
의뢰인(담배업자)은 발신인에게 미멘토를 요청(발송인의 내부 상태를 저장하기 위해)하고, 미멘토를 발신인에게 다시 전달(이전 상태로 복원하기 위해)할 수 있다.
이것은 발신자의 캡슐화를 위반하지 않고 발신자의 내부 상태를 저장 및 복원할 수 있다.
아래 UML 클래스 및 시퀀스 다이어그램을 참조하십시오.
구조
UML 클래스 및 시퀀스 다이어그램

위의 UML클래스 다이어그램에서Caretaker
class는 다음을 가리킨다.Originator
저장 클래스(createMemento()
) 및 복원(restore(memento)
) 발신자의 내부 상태.
그Originator
수업용구
(1)createMemento()
생성 및 반환Memento
발신자의 현재 내부 상태를 저장하는 개체
(2)restore(memento)
과거로부터 상태를 복원하여Memento
이의를 제기하다
UMLsequence 다이어그램은 런타임 교호작용을 보여준다.
(1) 발신자의 내부상태 저장:그Caretaker
반대 전화createMemento()
에서Originator
물체, 이 물체가 생성된다.Memento
객체, 현재 내부 상태 저장(setState()
) 및 반환Memento
에게Caretaker
.
(2) 발신자의 내부상태 복원:그Caretaker
전화를 하다restore(memento)
에서Originator
객체 및 지정Memento
복원해야 하는 상태를 저장하는 개체.그Originator
상태 파악(getState()
~에서Memento
자신의 입장을 정하기 위해서.
자바 예제
![]() | 위키북 컴퓨터 과학 디자인 패턴에는 다음과 같은 주제의 페이지가 있다: 다양한 언어로 된 메멘토 구현 |
다음 자바 프로그램은 미멘토 패턴의 "undo" 사용을 보여준다.
수입하다 java.util.리스트; 수입하다 java.util.배열 목록; 계급 기원자 { 사유의 끈 주; // 클래스에 다음 항목에 속하지 않는 추가 데이터가 포함될 수도 있음 // memento에 저장된 상태.. 공중의 공허하게 하다 세트(끈 주) { 이.주 = 주; 시스템.밖으로.인쇄하다("출발자:상태를 "로 설정하는 중 + 주); } 공중의 메멘토 saveToMemento() { 시스템.밖으로.인쇄하다("기원:메멘토에 저장."); 돌아오다 새로운 메멘토(이.주); } 공중의 공허하게 하다 restoreFromMemento(메멘토 메멘토) { 이.주 = 메멘토.GetSavedState(); 시스템.밖으로.인쇄하다("출발자:메멘토에서 복원 후 상태: " + 주); } 공중의 정태의 계급 메멘토 { 사유의 최종의 끈 주; 공중의 메멘토(끈 stateToSave) { 주 = stateToSave; } // 외부 클래스만 액세스할 수 있음 사유의 끈 GetSavedState() { 돌아오다 주; } } } 계급 관리인 { 공중의 정태의 공허하게 하다 본래의(끈[] 아그) { 리스트<기원자.메멘토> savedStates = 새로운 배열 목록<기원자.메멘토>(); 기원자 기원자 = 새로운 기원자(); 기원자.세트("상태1"); 기원자.세트("상태2"); savedStates.덧셈을(기원자.saveToMemento()); 기원자.세트("상태3"); // 여러 개의 기념품을 요청할 수 있고, 어떤 기념품으로 돌아갈지 선택할 수 있다. savedStates.덧셈을(기원자.saveToMemento()); 기원자.세트("스테이트4"); 기원자.restoreFromMemento(savedStates.얻다(1)); } }
출력:
발신자:State1 Originator로 상태 설정:State2 Originator로 상태 설정: Memento에 저장발신자:State3 Originator로 상태 설정: Memento에 저장발신자:State4 Originator로 상태 설정:메멘토에서 복원 후 상태:상태3
이 예는 Java에서 불변의 객체인 String을 state로 사용한다.실제상황 시나리오에서 국가는 거의 항상 변이 가능한 물체가 될 것이며, 이 경우 국가의 복사본이 만들어져야 한다.
표시된 구현에는 단점이 있다고 말해야 한다: 내부 계층을 선언한다는 것이다.이 메멘토 전략을 둘 이상의 발신자에게 적용할 수 있다면 더 좋을 것이다.
메멘토를 달성하는 다른 방법에는 주로 세 가지가 있다.
- 연재.
- 동일한 패키지로 선언된 클래스.
- 또한 객체에 대한 저장/복원 작업을 수행할 수 있는 프록시를 통해 객체에 액세스할 수 있다.
C# 예제
메멘토 패턴은 캡슐화를 위반하지 않고 물체의 내부 상태를 캡처할 수 있도록 하여 나중에 필요할 경우 변경 사항을 취소/반복할 수 있다.여기서 메멘토 객체가 실제로 객체의 변경사항을 되돌리기 위해 사용된다는 것을 알 수 있다.
계급 메멘토 { 사유의 읽기 전용 끈을 매다 savedState; 사유의 메멘토(끈을 매다 stateToSave) { savedState = stateToSave; } 공중의 계급 기원자 { 사유의 끈을 매다 주; // 클래스에 다음 항목에 속하지 않는 추가 데이터가 포함될 수도 있음 // memento에 저장된 상태. 공중의 공허하게 하다 세트(끈을 매다 주) { 콘솔.WriteLine("출발자:상태를 "로 설정하는 중 + 주); 이.주 = 주; } 공중의 메멘토 세이브토메멘토() { 콘솔.WriteLine("기원:메멘토에 저장."); 돌아오다 새로운 메멘토(주); } 공중의 공허하게 하다 RestoreFromMemento(메멘토 메멘토) { 주 = 메멘토.savedState; 콘솔.WriteLine("출발자:메멘토에서 복원 후 상태: " + 주); } } } 계급 관리인 { 정태의 공허하게 하다 메인(끈을 매다[] 아그) { 리스트<메멘토> savedStates = 새로운 리스트<메멘토>(); 메멘토.기원자 기원자 = 새로운 메멘토.기원자(); 기원자.세트("상태1"); 기원자.세트("상태2"); savedStates.추가하다(기원자.세이브토메멘토()); 기원자.세트("상태3"); // 여러 개의 기념품을 요청할 수 있고, 어떤 기념품으로 돌아갈지 선택할 수 있다. savedStates.추가하다(기원자.세이브토메멘토()); 기원자.세트("스테이트4"); 기원자.RestoreFromMemento(savedStates[1]); } }
파이톤 예
""" 메멘토 패턴 예시. """ 계급 메멘토: 반항하다 __init___(자아의, 주) -> 없음: 자아의._국가 = 주 반항하다 get_properties_state(자아의): 돌아오다 자아의._국가 계급 기원자: _국가 = "" 반항하다 세트(자아의, 주) -> 없음: 인쇄하다("출발자:상태를 "로 설정하는 중, 주) 자아의._국가 = 주 반항하다 save_to_memento(자아의) -> 메멘토: 인쇄하다("기원:메멘토에 저장.") 돌아오다 메멘토(자아의._국가) 반항하다 restore_from_memento(자아의, 메멘토) -> 없음: 자아의._국가 = 메멘토.get_properties_state() 인쇄하다("출발자:메멘토에서 복원 후 상태: ", 자아의._국가) saved_message = [] 기원자 = 기원자() 기원자.세트("상태1") 기원자.세트("상태2") saved_message.덧셈을(기원자.save_to_memento()) 기원자.세트("상태3") saved_message.덧셈을(기원자.save_to_memento()) 기원자.세트("스테이트4") 기원자.restore_from_memento(saved_message[1])
참조
- ^ Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley. pp. 283ff. ISBN 0-201-63361-2.
{{cite book}}
: CS1 maint : 복수이름 : 작성자 목록(링크) - ^ "The Memento design pattern - Problem, Solution, and Applicability". w3sDesign.com. Retrieved 2017-08-12.
- ^ "The Memento design pattern - Structure and Collaboration". w3sDesign.com. Retrieved 2017-08-12.
외부 링크
- 에이다의 메멘토 패턴 설명
- C# 및 가 포함된 Memento UML 클래스 다이어그램NET 코드 샘플
- SourceMaking 자습서
- 자바를 이용한 메멘토 디자인 패턴