목차
1. 메멘토 패턴(Memento Pattern) 이란?
2. 메멘토 패턴 구조 (Memento Pattern Structure)
3. 예제
메멘토 패턴 (Memento Pattern) 이란?
Memento 는 "추억" 또는 "과거의 기억" 이라는 단어를 뜻합니다.
단어의 의미에 알맞게 메멘토 패턴은 객체의 상태에 대한 기억을 저장해 두었다가 필요할때
기억해둔 상태로 객체를 되돌릴 수 있는 행동 디자인 패턴 입니다.
이 기억은 다른 객체에서도 읽기 전용으로 접근할 수 있으며, 해당 기억은 오직 해당 객체만 할 수 있는 특징이 있습니다.
메멘토 패턴 구조 (Memento Pattern Structure)
이름 | 내용 |
Walker | 걷기를 수행할 클래스 |
Memento | 현재 위치를 기억하는 내부 클래스 |
Main | 메인 클래스 |
예제
Walker 클래스
필드로는 현재 위치(currentX, currentY) 와 목적지 (targetX, targetY) 를 좌표로 두고 있습니다.
그리고 이동 경로를 저장할 actionList 를 배열로 두었습니다.
기본 생성자로 현재 위치 와 목적지를 받아 인스턴스를 생성합니다.
walk 메서드를 통해 방향을 인식하여 현재 위치를 갱신 하고, 목적지와의 거리를 계산하여 리턴합니다.
createMemento 를 통해 내부 클래스인 Memento 클래스를 생성합니다.
restoreMemento 는 생성한 Memento 클래스는 반환받아 과거 기억을 가져오는 역할을 합니다.
createMemento 와 restoreMemento 메서드에서 볼 수 있는 것이 clone 메서드 입니다.
만약 clone 을 사용 하지 않고 리스트를 반환 한다면, 해당 리스트가 변하게 될때 Memento 필드의 List 의 상태도 변하게
됩니다.
Memento 내부 클래스
좌표 (x, y) 와 이동 경로를 저장할 List 를 필드로 가지고 있습니다.
public class Walker {
private int currentX, currentY;
private int targetX, targetY;
private ArrayList<String> actionList = new ArrayList<>();
public Walker(int currentX, int currentY, int targetX, int targetY) {
this.currentX = currentX;
this.currentY = currentY;
this.targetX = targetX;
this.targetY = targetY;
}
public double walk(String action) {
actionList.add(action);
if(action.equals("UP")) {
currentY += 1;
} else if(action.equals("RIGHT")) {
currentX += 1;
} else if(action.equals("DOWN")) {
currentY -= 1;
} else if(action.equals("LEFT")) {
currentX -= 1;
}
return Math.sqrt(Math.pow(currentX - targetX, 2) + Math.pow(currentY - targetY, 2));
}
public class Memento {
private int x, y;
private ArrayList<String> actionList;
private Memento() {}
}
public Memento createMemento() {
Memento memento = new Memento();
memento.x = this.currentX;
memento.y = this.currentY;
memento.actionList = (ArrayList<String>) this.actionList.clone(); // clone
return memento;
}
// clone 메서드를 통해 Memento 와 Walker 의 필드에 존재하는 List가 독립적으로 동작합니다.
public void restoreMemento(Memento memento) {
this.currentX = memento.x;
this.currentY = memento.y;
this.actionList = (ArrayList<String>) memento.actionList.clone(); // clone
}
@Override
public String toString() {
return actionList.toString();
}
}
Main 클래스
Walker 를 생성하고 actions 문자배열에 방향을 넣습니다.
Random 객체를 이용하여 방향 중 하나를 랜덤하게 뽑습니다.
거리가 0이 되면 종료하고 거리가 가까워 질 수록 거리를 갱신하고,
거리가 멀어졌다면 이전 상태로 돌아갑니다.
public class Main {
public static void main(String[] args) {
Walker walker = new Walker(0,0,10,10);
String[] actions = {"UP", "RIGHT", "DOWN", "LEFT"};
Random random = new Random();
double minDistance = Double.MAX_VALUE;
Walker.Memento memento = null;
while(true) {
String action = actions[random.nextInt(4)];
double distance = walker.walk(action);
System.out.println(action + " " + distance);
if(distance == 0.0) {
break;
}
if(minDistance > distance) {
minDistance = distance;
memento = walker.createMemento();
} else {
if(memento != null){
walker.restoreMemento(memento);
}
}
}
System.out.println("Walker's path: " + walker);
}
}
실행 결과
RIGHT 6.4031242374328485
RIGHT 5.830951894845301
LEFT 6.4031242374328485
LEFT 6.4031242374328485
RIGHT 5.385164807134504
LEFT 5.830951894845301
UP 4.47213595499958
UP 3.605551275463989
RIGHT 3.1622776601683795
DOWN 4.123105625617661
RIGHT 3.0
LEFT 3.1622776601683795
DOWN 4.0
RIGHT 3.1622776601683795
LEFT 3.1622776601683795
UP 2.0
RIGHT 2.23606797749979
DOWN 3.0
DOWN 3.0
UP 1.0
RIGHT 1.4142135623730951
UP 0.0
Walker's path: [RIGHT, RIGHT, RIGHT, UP, UP, RIGHT, RIGHT, UP, UP, UP]
참조
https://www.youtube.com/watch?v=l8SfShTTiNY&list=PLe6NQuuFBu7FhPfxkjDd2cWnTy2y_w_jZ&index=13
'Design Pattern > 생성(Creational) 패턴' 카테고리의 다른 글
2. 싱글톤 패턴 (Singleton Pattern) (1) | 2023.10.28 |
---|