728x90
출처 : 책 - java 언어로 배우는 디자인 패턴 입문
18. Memento - 상태를 저장하기
1. 목적
- 말 그대로 현재 상태를 저장하는 구조이다.
- 유의해서 볼 점은 상태를 저장한 클래스의 메소드에 public이 없다는 점이다.(예제에서는 1개만 있음)
은닉하기 위함.
- 의의 : 저장한 상태를 따로 분리함으로써, 저장한 상태를 파일로 만드는 작업등을 추가로 할 때
오리지날 클래스는 건드리지 않도록 유지할 수 있다.
2. 예제
(1) Memento - 상태 저장. getMoney 메소드만 public 선언이 되어있다. (정보 은닉)
같은 패키지인 Gamer 클래스에서만 Memento 메소드를 사용할 수 있고, Main에서는 호출할 수 없다.
package game;
import java.util.*;
public class Memento {
int money; // 소지금
ArrayList fruits; // 과일
public int getMoney() { // 소지금을 얻는다(narrow interface)
return money;
}
Memento(int money) { // 생성자(wide interface)
this.money = money;
this.fruits = new ArrayList();
}
void addFruit(String fruit) { // 과일을 추가한다(wide interface)
fruits.add(fruit);
}
List getFruits() { // 과일을 얻는다(wide interface)
return (List)fruits.clone();
}
}
(2) Gamer - Memento를 사용하는 역할. createMemento(), restoreMemento(Memento memento)
package game;
import java.util.*;
public class Gamer {
private int money; // 소지금
private List fruits = new ArrayList(); // 과일
private Random random = new Random(); // 난수발생기
private static String[] fruitsname = { // 과일 이름의 표
"사과", "포도", "바나나", "귤",
};
public Gamer(int money) { // 생성자
this.money = money;
}
public int getMoney() { // 현재의 소지금을 얻는다
return money;
}
public void bet() { // 내기하다 - 게임의 진행
int dice = random.nextInt(6) + 1; // 주사위를 던지다
if (dice == 1) { // 1 - 소지금이 증가한다
money += 100;
System.out.println("소지금이 증가했습니다.");
} else if (dice == 2) { // 2 - 소지금이 절반이 된다
money /= 2;
System.out.println("소지금이 절반이 되었습니다.");
} else if (dice == 6) { // 6 - 과일을 받는다
String f = getFruit();
System.out.println("과일(" + f + ")을 받았습니다.");
fruits.add(f);
} else { // 그외 - 변한 것이 없다
System.out.println("변한 것이 없습니다.");
}
}
public Memento createMemento() { // 스냅샷을 찍는다
Memento m = new Memento(money);
Iterator it = fruits.iterator();
while (it.hasNext()) {
String f = (String)it.next();
if (f.startsWith("맛있는 ")) { // 과일은 맛있는 것만 보존
m.addFruit(f);
}
}
return m;
}
public void restoreMemento(Memento memento) { // undo 실행
this.money = memento.money;
this.fruits = memento.getFruits();
}
public String toString() { // 문자열 표현
return "[money = " + money + ", fruits = " + fruits + "]";
}
private String getFruit() { // 과일을 1개 얻는다
String prefix = "";
if (random.nextBoolean()) {
prefix = "맛있는 ";
}
return prefix + fruitsname[random.nextInt(fruitsname.length)];
}
}
(3) Main - Memento의 저장조건을 설정해준다.
import game.Memento;
import game.Gamer;
public class Main {
public static void main(String[] args) {
Gamer gamer = new Gamer(100); // 최초의 소지금은 100
Memento memento = gamer.createMemento(); // 최초의 상태를 저장해 둔다
for (int i = 0; i < 100; i++) {
System.out.println("==== " + i); // 개수 표시
System.out.println("현상:" + gamer); // 현재의 주인공의 상태 표시
gamer.bet(); // 게임을 진행시킨다
System.out.println("소지금은" + gamer.getMoney() + "원이 되었습니다.");
// Memento의 취급 결정
if (gamer.getMoney() > memento.getMoney()) {
System.out.println(" (많이 증가했으므로 현재의 상태를 저장하자)");
memento = gamer.createMemento();
} else if (gamer.getMoney() < memento.getMoney() / 2) {
System.out.println(" (많이 감소했으므로 이전의 상태로 복원하자)");
gamer.restoreMemento(memento);
}
// 시간 기다림
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.println("");
}
}
}
728x90
'개발 > 디자인 패턴' 카테고리의 다른 글
[Java 언어로 배우는 디자인 패턴 입문] 낭비 없애기 20. Flyweight (0) | 2021.01.17 |
---|---|
[Java 언어로 배우는 디자인 패턴 입문] 상태를 관리하기 19. State (0) | 2021.01.17 |
[Java 언어로 배우는 디자인 패턴 입문] 상태를 관리하기 17. Observer (0) | 2021.01.14 |
[Java 언어로 배우는 디자인 패턴 입문] 단순화하기 16. Mediator (0) | 2021.01.13 |
[Java 언어로 배우는 디자인 패턴 입문] 단순화하기 15. Facade (0) | 2021.01.12 |
댓글