Memento Pattern
Memento Pattern(메멘토 패턴)이란?
: 어느 시점에서 인스턴스 상태를 확실하게 기록하여 저장해 두고, 나중에 인스턴스를 그 시점의 상태로 되돌려주는 패턴입니다.
우리가 문서작업을 할 때 흔히 사용하는 '되돌리기'기능을 생각하시면 편합니다. 바로 예제를 살펴보겠습니다.
여기 게임속에서 움직이는 플레이어가 있습니다.
class Player {
private int x;
private int y;
public void move(int x, int y) {
this.x = x;
this.y = y;
}
public void printPosition() {
System.out.println("현재 플레이어 위치: (" + x + ", " + y + ")");
}
}
이 플레이어는 move로 해당 위치로 이동하고 printPosition()으로 위치를 출력해주는 클래스입니다. 이 플레이어는 이렇게 움직일 것입니다.
public class GameExample {
public static void main(String[] args) {
Player player = new Player();
player.move(10, 20);
player.move(15, 25);
player.printPosition();
}
}
이렇게 플레이어가 이동한다고 할 때, 만약 전에 이동한곳으로 '되돌아가고'싶다면 어떻게 해야 할까요? 다시 그 위치의 값을 move에 넣는것은 되돌아 가는것이 아니라 재이동하는것이기 때문에 맞지 않습니다. 이때 Memento패턴이 등장합니다.
먼저 Player와 같은 변수를 갖는 PlayerMemento 클래스를 생성합니다.
// Memento 객체: 플레이어의 위치를 저장하는 역할
class PlayerMemento {
private int x;
private int y;
PlayerMemento(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
이 객체는 플레이어와 동일하게 각 좌표값을 생성자를 통해 저장하고 있습니다. 하지만 플레이어 객체와 다르게 get메소드가 포함되어 있습니다. 또한, 생성자를 보시면 public 접근제어자가 없음을 볼 수 있는데 이는 같은 패키지내에서만 생성가능하도록 제어하기 위함(캡슐화)입니다.(Default : 같은 패키지 내에서만 접근가능) 이제 플레이어 객체에서 Memento를 생성 및 저장을 하겠습니다.
#변경된 Player클래스
// Originator 객체: 플레이어의 위치를 저장하고 복원하는 역할
class Player {
private int x;
private int y;
public void move(int x, int y) {
this.x = x;
this.y = y;
}
public PlayerMemento savePlayerToMemento() {
return new PlayerMemento(x, y);
}
public void restorePlayerFromMemento(PlayerMemento memento) {
this.x = memento.getX();
this.y = memento.getY();
}
public void printPosition() {
System.out.println("현재 플레이어 위치: (" + x + ", " + y + ")");
}
}
플레이어에 Memento를 생성하고 저장 및 복원하는 메소드가 추가되었습니다. 이제 Memento객체에 전에 이동했던 좌표를 저장할 수 있습니다.
#변경된 Main클래스
public class GameExample {
public static void main(String[] args) {
Player player = new Player();
// 초기 플레이어 위치 설정 및 저장
player.move(10, 20);
PlayerMemento memento = player.savePlayerToMemento();
// 플레이어 이동
player.move(15, 25);
// 이전 위치로 복원
player.restorePlayerFromMemento(memento);
player.printPosition();
}
}
이렇게하면 플레이어의 마지막위치는 15 , 25가 아닌 10 , 20으로 돌아가게 됩니다.
장점
- 상태의 캡슐화: Memento 패턴은 상태를 캡슐화하여 Originator 객체 외부에서 상태를 변경할 수 없도록 합니다. 이는 객체의 캡슐화를 유지하고 객체의 무결성을 보호하는 데 도움이 됩니다.
- 상태의 이력 관리: Memento 패턴은 객체의 상태를 시간에 따라 저장하고 관리할 수 있습니다. 이전 상태로 쉽게 복원할 수 있으므로 객체의 이력을 관리하는 데 유용합니다. 이는 "되돌리기(undo)" 기능 등을 구현할 때 유용합니다.
- 상태의 외부 저장: Memento 패턴을 사용하면 상태를 외부에 저장할 수 있습니다. 이는 상태를 영구적으로 보존하거나 다른 객체와 공유하는 데 유용합니다.
단점
- 메모리 사용량: Memento 패턴을 사용하면 상태의 이력을 유지하기 위해 메모리를 추가적으로 사용해야 합니다. 따라서 상태의 크기가 큰 경우에는 메모리 사용량이 증가할 수 있습니다.
- 성능 저하: 객체의 상태를 저장하고 복원하는 과정은 추가적인 연산을 필요로 합니다. 이는 성능에 영향을 줄 수 있으며, 특히 상태의 크기가 큰 경우에는 성능 저하가 더욱 두드러질 수 있습니다.
정리
Memento 패턴은 객체의 상태를 저장하고 이후에 복원할 수 있는 디자인 패턴으로, 상태를 캡슐화하여 객체의 무결성을 유지하고 상태 이력을 관리하는 데 활용됩니다. 상태 저장과 복원을 위한 메커니즘을 제공하여 객체의 이전 상태로 되돌릴 수 있게 합니다.