Develop Story/DesignPattern

Memento Pattern

박은유 2024. 4. 15. 10:06
반응형

Memento Pattern(메멘토 패턴)이란?

 : 어느 시점에서 인스턴스 상태를 확실하게 기록하여 저장해 두고, 나중에 인스턴스를 그 시점의 상태로 되돌려주는 패턴입니다.

 

우리가 문서작업을 할 때 흔히 사용하는 '되돌리기'기능을 생각하시면 편합니다. 바로 예제를 살펴보겠습니다.

 

여기 게임속에서 움직이는 플레이어가 있습니다.

 

class Player {
    private int x;
    private int y;

    public void move(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void printPosition() {
        System.out.println("현재 플레이어 위치: (" + x + ", " + y + ")");
    }
}

 

이 플레이어는 move로 해당 위치로 이동하고 printPosition()으로 위치를 출력해주는 클래스입니다. 이 플레이어는 이렇게 움직일 것입니다.

 

public class GameExample {
    public static void main(String[] args) {
        Player player = new Player();
        
        player.move(10, 20);

        player.move(15, 25);
	player.printPosition();
        
    }
}

 

이렇게 플레이어가 이동한다고 할 때, 만약 전에 이동한곳으로 '되돌아가고'싶다면 어떻게 해야 할까요? 다시 그 위치의 값을 move에 넣는것은 되돌아 가는것이 아니라 재이동하는것이기 때문에 맞지 않습니다. 이때 Memento패턴이 등장합니다.

 

먼저 Player와 같은 변수를 갖는 PlayerMemento 클래스를 생성합니다.

// Memento 객체: 플레이어의 위치를 저장하는 역할
class PlayerMemento {
    private int x;
    private int y;

    PlayerMemento(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }
}

 

이 객체는 플레이어와 동일하게 각 좌표값을 생성자를 통해 저장하고 있습니다. 하지만 플레이어 객체와 다르게 get메소드가 포함되어 있습니다. 또한, 생성자를 보시면 public 접근제어자가 없음을 볼 수 있는데 이는 같은 패키지내에서만 생성가능하도록 제어하기 위함(캡슐화)입니다.(Default : 같은 패키지 내에서만 접근가능) 이제 플레이어 객체에서 Memento를 생성 및 저장을 하겠습니다.

 

#변경된 Player클래스

// Originator 객체: 플레이어의 위치를 저장하고 복원하는 역할
class Player {
    private int x;
    private int y;

    public void move(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public PlayerMemento savePlayerToMemento() {
        return new PlayerMemento(x, y);
    }

    public void restorePlayerFromMemento(PlayerMemento memento) {
        this.x = memento.getX();
        this.y = memento.getY();
    }

    public void printPosition() {
        System.out.println("현재 플레이어 위치: (" + x + ", " + y + ")");
    }
}

 

플레이어에 Memento를 생성하고 저장 및 복원하는 메소드가 추가되었습니다. 이제 Memento객체에 전에 이동했던 좌표를 저장할 수 있습니다.

 

#변경된 Main클래스

public class GameExample {
    public static void main(String[] args) {
        Player player = new Player();

        // 초기 플레이어 위치 설정 및 저장
        player.move(10, 20);
        PlayerMemento memento = player.savePlayerToMemento();

        // 플레이어 이동
        player.move(15, 25);

        // 이전 위치로 복원
        player.restorePlayerFromMemento(memento);
        player.printPosition();
    }
}

 

이렇게하면 플레이어의 마지막위치는 15 , 25가 아닌 10 , 20으로 돌아가게 됩니다.

 

장점

  1. 상태의 캡슐화: Memento 패턴은 상태를 캡슐화하여 Originator 객체 외부에서 상태를 변경할 수 없도록 합니다. 이는 객체의 캡슐화를 유지하고 객체의 무결성을 보호하는 데 도움이 됩니다.
  2. 상태의 이력 관리: Memento 패턴은 객체의 상태를 시간에 따라 저장하고 관리할 수 있습니다. 이전 상태로 쉽게 복원할 수 있으므로 객체의 이력을 관리하는 데 유용합니다. 이는 "되돌리기(undo)" 기능 등을 구현할 때 유용합니다.
  3. 상태의 외부 저장: Memento 패턴을 사용하면 상태를 외부에 저장할 수 있습니다. 이는 상태를 영구적으로 보존하거나 다른 객체와 공유하는 데 유용합니다.

 

단점

  1. 메모리 사용량: Memento 패턴을 사용하면 상태의 이력을 유지하기 위해 메모리를 추가적으로 사용해야 합니다. 따라서 상태의 크기가 큰 경우에는 메모리 사용량이 증가할 수 있습니다.
  2. 성능 저하: 객체의 상태를 저장하고 복원하는 과정은 추가적인 연산을 필요로 합니다. 이는 성능에 영향을 줄 수 있으며, 특히 상태의 크기가 큰 경우에는 성능 저하가 더욱 두드러질 수 있습니다.

 

정리

Memento 패턴은 객체의 상태를 저장하고 이후에 복원할 수 있는 디자인 패턴으로, 상태를 캡슐화하여 객체의 무결성을 유지하고 상태 이력을 관리하는 데 활용됩니다. 상태 저장과 복원을 위한 메커니즘을 제공하여 객체의 이전 상태로 되돌릴 수 있게 합니다.

반응형