Design Pattern : 메멘토(Memento) 패턴
메멘토(Memento) 패턴
메멘토 패턴은 캡슐화를 유지하면서 객체 내부 상태를 외부에 저장하는 패턴입니다.
1. 다이어그램
Originator
: 객체의 정보를 가지고 있는 오리지널 객체- 제 3자가 객체 내부 정보를 알지 못하게 하기 위하여 Memento를 만들 수 있는 메서드가 필요함
Memento
: 오리지널 객체의 정보를 담는 불변 객체CareTaker
: 오리지널이 반환한 Memento를 가지고 있다가 필요할 때 Memento의 값을 Originator에게 전달함
2. 예시 코드
너무 간단한 패턴이라 코드만 봐도 쉽게 이해할 수 있을 거라 생각합니다.
2-1. 메멘토 패턴 적용 전
Game 객체의 정보를 복원하기 위하여 저장을 해야할 때 외부에 객체의 정보를 노출함으로써 캡슐화를 지킬 수 없게 됩니다.
// 게임 객체
public class Game implements Serializable {
private int redTeamScore;
private int blueTeamScore;
public int getRedTeamScore() {
return redTeamScore;
}
public void setRedTeamScore(int redTeamScore) {
this.redTeamScore = redTeamScore;
}
public int getBlueTeamScore() {
return blueTeamScore;
}
public void setBlueTeamScore(int blueTeamScore) {
this.blueTeamScore = blueTeamScore;
}
}
// 클라이언트, CareTaker로 볼 수 있음
public class Client {
public static void main(String[] args) {
Game game = new Game();
game.setRedTeamScore(10);
game.setBlueTeamScore(20);
// 게임을 복원하기 위해서 게임의 정보를 노출
int blueTeamScore = game.getBlueTeamScore();
int redTeamScore = game.getRedTeamScore();
// 외부에 저장한 게임의 정보를 그대로 가져와서 새로운 게임을 만듬 -> 캡슐화 깨짐
Game restoredGame = new Game();
restoredGame.setBlueTeamScore(blueTeamScore);
restoredGame.setRedTeamScore(redTeamScore);
}
}
2-2. 메멘토 패턴 적용 후
Game 객체의 정보를 복원하기 위하여 저장을 해야할 때 GameSave 불변 객체를 이용함으로써 외부에 객체의 정보를 감추어, 캡슐화를 지킬 수 있습니다.
// 게임 객체
public class Game {
private int redTeamScore;
private int blueTeamScore;
public int getRedTeamScore() {
return redTeamScore;
}
public void setRedTeamScore(int redTeamScore) {
this.redTeamScore = redTeamScore;
}
public int getBlueTeamScore() {
return blueTeamScore;
}
public void setBlueTeamScore(int blueTeamScore) {
this.blueTeamScore = blueTeamScore;
}
public GameSave save() {
return new GameSave(this.blueTeamScore, this.redTeamScore);
}
public void restore(GameSave gameSave) {
this.blueTeamScore = gameSave.getBlueTeamScore();
this.redTeamScore = gameSave.getRedTeamScore();
}
}
// 게임 정보를 저장하는 불변 객체
public final class GameSave {
private final int blueTeamScore;
private final int redTeamScore;
public GameSave(int blueTeamScore, int redTeamScore) {
this.blueTeamScore = blueTeamScore;
this.redTeamScore = redTeamScore;
}
public int getBlueTeamScore() {
return blueTeamScore;
}
public int getRedTeamScore() {
return redTeamScore;
}
}
// 클라이언트, CareTaker로 볼 수 있음
public class Client {
public static void main(String[] args) {
Game game = new Game();
game.setBlueTeamScore(10);
game.setRedTeamScore(20);
// 위와 다르게 클라이언트에서 게임의 정보를 가지고 있는 것이 아니라 불변 객체인 GameSave를 가짐
GameSave save = game.save();
game.setBlueTeamScore(12);
game.setRedTeamScore(22);
// GameSave를 받아서 정보 복원
game.restore(save);
System.out.println(game.getBlueTeamScore());
System.out.println(game.getRedTeamScore());
}
}
2-3. 객체 간의 관계도
3. 장점과 단점
메멘토 패턴의 장점과 단점은 아래와 같습니다.
3-1. 장점
- 캡슐화를 지키면서 상태 객체 상태 스냅샷을 만들 수 있습니다.
스냅샷
: 객체의 특정 시점의 데이터를 저장해 놓는 것
-
객체 상태 저장하고 또는 복원하는 역할을 CareTaker에게 위임할 수 있습니다.
- 객체 상태가 바뀌어도 클라이언트 코드는 변경되지 않습니다.
3-2. 단점
- 많은 정보를 저장하는 Mementor를 자주 생성하는 경우 메모리 사용량에 많은 영향을 줄 수 있습니다.
4. 마치며…
메멘토 패턴은 객체의 특정 시점 상태를 저장할 수 있는데, 이 때, 객체와 거의 동일한 메멘토 객체를 만들기 때문에 객체의 크기가 커질수록 메모리 사용량에 영향을 줄 확률이 높아지므로 상황에 따라 적절히 사용할 수 있어야 합니다.
댓글남기기