-
[디자인패턴] 메멘토패턴기타/북스터디 2023. 1. 29. 08:58
1. 메멘토패턴(memento pattern)이란?
메멘토패턴은 객체 내부의 상태를 외부에 저장을 하고 저장된 상태를 다시 복원하고자 할 때에 사용하는 패턴이다.
메멘토패턴을 사용함으로써 객체의 모든 정보를 외부로 노출시키지 않고 캡슐화를 지킬 수 있다.
Originator는 본래의 상태를 가지고 있고 상태를 저장하고 복원하고 싶어하는 객체이다.
Memento는 immutable한 객체로 일정 시점의 Originator 내부정보를 가지고 있다.
CareTaker는 Originator의 내부정보를 Memento type으로 가지고 있고 복원을 할 수 있는 객체이다.
2. 메멘토패턴을 사용하지 않은 코드
게임의 현재 스테이지와 캐릭터의 정보를 가지고 있는 클래스가 있다고 가정해보자.
public class Game { private int stage; private Character character; public int getStage() { return stage; } public void setStage(int stage) { this.stage = stage; } public Character getCharacter() { return character; } public void setCharacter(Character character) { this.character = character; } }
그리고 게임이 진행 중에 이전 시점으로 돌리는 상황을 가정한 클라이언트를 코드를 봐보자.
public class Client { public static void main(String[] args) { Game game = new Game(); game.setStage(10); game.setCharacter(new Character()); int stage = game.getStage(); Character character = game.getCharacter(); Game restoredGame = new Game(); restoredGame.setStage(stage); restoredGame.setCharacter(character); } }
위와 같은 코드의 문제점은 아래와 같다.
1. 캡슐화가 깨지게 된다.
- 클라이언트가 게임이 구성하는 요소가 무엇인지 알게 된다.
2. 클라이언트가 Game객체에 의존하게 된다.
- Game의 멤버가 바뀜에 따라 클라이언트 코드가 바뀌어야한다.
3. 메멘토패턴을 적용해보자.
먼저, 메멘토 클래스를 만들어보자.
public final class GameSave { private final int stage; private final Character character; public GameSave(int stage, Character character) { this.stage = stage; this.character = character; } public int getStage() { return stage; } public Character getCharacter() { return character; } }
그리고 Originator인 Game 클래스에서는 메멘토를 사용하여 저장하고 복원할 수 있는 메서드를 만들어주자.
public class Game { private int stage; private Character character; public int getStage() { return stage; } public void setStage(int stage) { this.stage = stage; } public Character getCharacter() { return character; } public void setCharacter(Character character) { this.character = character; } public GameSave save() { return new GameSave(this.stage, this.character); } public Game restore(GameSave gameSave) { this.stage = gameSave.getStage(); this.character = gameSave.getCharacter(); } }
이렇게 Originator와 Memento를 만들어주면 클라이언트 코드는 아래와 같이 변경된다.
public class Client { public static void main(String[] args) { Game game = new Game(); game.setStage(10); game.setCharacter(new Character(1, "memento")); GameSave save = game.save(); game.setStage(12); game.setCharacter((new Character(15, "visitor"))); game.restore(save); System.out.println(game.getStage()); System.out.println(game.getCharacter().getLevel()); System.out.println(game.getCharacter().getName()); } }
실행을 시켜보면 아래와 같이 game의 이전 정보가 보여지는 것을 볼 수 있다.
'기타 > 북스터디' 카테고리의 다른 글
[디자인패턴] 비지터패턴 (0) 2023.01.29 [이펙티브 자바] 아이템24. 멤버 클래스는 되도록 static으로 만들라 (0) 2023.01.09 [디자인패턴] 프록시패턴 (0) 2023.01.08 [이펙티브 자바] 아이템12. toString을 항상 재정의하라 (0) 2023.01.02 [디자인패턴] 커맨드패턴 (0) 2022.12.25