본문 바로가기

코딩/Software Architecture

[GoF Design Pattern] Memento

* Memento Pattern : 객체의 상태를 기억해 두었다가, 필요한 시점에 기억해둔 상태로 객체를 되돌리는 패턴.

객체의 상태에 대한 기억은 다른 객체에서도 "읽기 전용"으로 접근할 수 있다. (다른 객체에선 변경 불가)

객체의 상태에 대한 기억의 생성은 오직 해당 객체에서만 할 수 있다. (다른 곳에선 생성 불가)

Walker : 시작 지점에서 목표 지점까지 걸어감 (기억을 Memento에 남김?)

Memento : 과거의 기억인 Memento 클래스를 통해 시작 지점부터 목표 지점까지 점점 가까워 짐. (최소 거리를 통해)

                  walker의 내부 클래스인 이유: Walker 클래스에서만 생성할 수 있도록 하고, 오직 Walker 클래스만 Memento의 필드를 변경하기 위함.

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 currentX-targetX + currentY-targetY;
    }
    
    public class Memento {   // innerclass
    	private int x,y;
        private ArrayList<String> actionList;
        private Memento() {}
    }
    
    public Memento createMemento() { // 현재 상태를 Memento 에 저장.
    	Memento memento = new Memento();
        
        memento.x = thus.currentX;
        memento.y = thus.currentY;
        memento.actionList = (ArrayList<String>)this.actionList.clone();
        
        return memento;
    }
    
    public void restoreMemento(Memento memento) { // Memento 저장된걸 복구
    this.currentX = memento.x;
    this.currentY = memento.y;
    this.actionList = (ArrayList<String>)memento.actionList.clone();
    }
}
// Walk 와 Memento를 사용하는 예

public class MainEntry {
    public static void main(String[] args) {
    	Walker walker = new Walker(0, 0, 10, 10);
        String[] actions = {"UP", "RIGHT", "DOWN", "LEFT"};
        Random random = new Random();
        doublc 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.creatMemento();
            } else {
            	if(memento != null) { // 현재 위치가 최소가 아니면 직전 기억으로 이동
                	walker.restoreMemento(memento);
                }
            }
        }
    }
}

 

'코딩 > Software Architecture' 카테고리의 다른 글

[GoF Design Pattern] Mediator  (0) 2022.12.06
[GoF Design Pattern] Decorator  (0) 2022.12.05
[GoF Design Pattern] Builder  (0) 2022.12.04
[GoF Design Pattern] Facade  (0) 2022.12.04
[GoF Design Pattern] Flyweight  (0) 2022.12.04