Memento
Memento pattern - 행위 패턴
사용 목적
메멘토 패턴은 객체의 상태 정보를 저장하고 사용자의 필요에 의하여 원하는 시점의 데이터를 복원 할 수 있는 패턴을 의미합니다. 즉,
-
어떤 객체의 상태에 대한 스냅샷(몇 개의 일부)을 저장한 후 나중에 이 상태로 복구해야 할 때.
-
상태를 얻는 데 필요한 직접적인 인터페이스를 두면 그 객체의 구현 세부사항이 드러날 수밖에 없고, 이것으로 객체의 캡슐화가 깨질 때.
UML Diagram
-
Memento(SolverState) : 원조본 객체의 내부 상태를 저장하는 클래스. 이상적인 메멘토 생성은 원조본 객체만이 메멘토의 내부 상태에 접근할 수 있어야 합니다.
-
Originator(ConstraintSolver) : 원조본 객체. 메멘토를 생성하여 현재 상태를 저장하고, 메멘토를 사용하여 내부 상태를 복원합니다. 또한, 메멘토 클래스의 두 가지 인터페이스 중 광범위 인터페이스를 담당합니다. 즉, 자신의 상태를 이전 상태로 복원하기 위해 필요한 모든 자료에 접근하게 해주는 클래스.
-
Caretaker(실행 취소 메커니즘) : 메멘토의 보관을 책임지는 보관자. 메멘토의 내용을 검사하거나 그 내용을 건드리지는 않습니다. 또한, 메멘토 클래스의 두 가지 인터페이스 중 제한범위 인터페이스에 해당합니다.
예제
-
User : 메멘토 패턴이 적용 된 Information 객체를 실제로 사용하는 사용자.
-
Information : 상태를 저장하고 복원 할 데이터를 가지고 있는 클래스. -> Originator
-
Memento : 특정 시점의 Information의 상태정보를 저장하는 클래스. -> Memento
-
CareTaker : 상태 정보가 저장되어 있는 Memento들을 관리하는 클래스입니다. 내부에 Stack 자료형 변수를 가짐으로써 Memento 객체를 저장하고 복원을 합니다. (스택이 아닌 리스트나 맵 계열도 사용 가능함. 순차적인 기억 정보를 불러오는 스택과 달리 인덱스, 혹은 키/밸류를 이용한 상태 정보 저장과 불러오기가 가능함.)
// Originator 를 통해서만 상태를 저장하고, 복원하는것이 가능하다.
public class Information {
private String Data1; //Information이 가지고 있는 데이터1
private int Data2; //Information이 가지고 있는 데이터2
public Information(String Data1, int Data2) {
this.Data1 = Data1;
this.Data2 = Data2;
}
public Memento CreateMemento() { //Memento를 생성합니다 (상태저장)
return new Memento(this.Data1,this.Data2);
}
public void RestoreMemento(Memento memento) { //Memento를 복원합니다 (상태복원)
this.Data1 = memento.getData1();
this.Data2 = memento.getData2();
}
public void set_Data1(String Data1){
this.Data1 = Data1;
}
public void set_Data2(int Data2){
this.Data2 = Data2;
}
public String get_Data1() {
return this.Data1;
}
public int get_Data2() {
return this.Data2;
}
}
// 생성자를 통한 상태 정보 저장과, 불러오기를 담당함.
public class Memento {
//Information의 상태정보를 가지고 있음
private String Data1;
private int Data2;
public Memento(String Data1,int Data2){
this.Data1 = Data1;
this.Data2 = Data2;
}
public String getData1(){
return this.Data1;
}
public int getData2(){
return this.Data2;
}
}
public class Caretaker {
Stack<Memento> mementos = new Stack<>(); //Memento 관리를 위한 Stack
public void push(Memento memento){ //특정 시점에 생성된 Memento를 Push
mementos.push(memento);
}
public Memento pop(){ //복원을 위한 Memento 객체 반환{
return mementos.pop();
}
}
public class User {
public static void main(String[] args) {
Information info;
Caretaker caretaker;
info = new Information("Data1", 10); //Information 객체 생성
caretaker = new Caretaker(); //CareTaker 객체 생성
//현재 Information의 상태 정보를 가지는 Memento를 생성하여 CareTaker에 추가합니다.
caretaker.push(info.CreateMemento());
//Information 정보를 수정합니다.
info.set_Data1("Data2");
info.set_Data2(20);
//현재 Information의 상태정보를 출력합니다.
System.out.println("현재 Data1 : " + info.get_Data1());
System.out.println("현재 Data2 : " + info.get_Data2());
//가장 최근에 생성 된 Memento를 가지고와서 상태 정보를 복원합니다.
info.RestoreMemento(caretaker.pop());
//상태 정보를 복원 한 후에 Information의 상태 정보를 출력합니다.
System.out.println("복구된 Data1 : " + info.get_Data1());
System.out.println("복구된 Data2 : " + info.get_Data2());
}
}
참고 자료
- https://keichee.tistory.com/category/Programming/GoF%20Design%20Pattern
- https://lktprogrammer.tistory.com/65
- https://kunoo.tistory.com/entry/%ED%96%89%EC%9C%84-%ED%8C%A8%ED%84%B4-Memento-pattern-%EB%A9%94%EB%A9%98%ED%86%A0-%ED%8C%A8%ED%84%B4
- GOF Design Pattern