본문 바로가기
이론/GoF

[행동패턴] 메멘토 패턴

by 혀끄니 2023. 8. 21.
728x90
  • 메멘토(Memento)패턴

- 캡슐화를 유지하면서 객체 내부 상태를 외부에 저장하는 방법

- 객체 상태를 외부에 저장했다가 해당 상태로 다시 복귀할 수 있다.

originator : 원래의 내부정보를 가지고 있는 데이터 객체

- createMementor() : 내부정보를 Memento클래스로 추상화하여 전달하는 Operation

- restore() : 외부에서 전달받은 Memento 정보를 복원할 수 있는 기능을 제공하는 Operation

care taker : Originator 정보를 가지고와 복원

- Originator정보를 추상화 해둔 Memento타입으로 가지고 있음

Memento : 원래의 내부정보를 추상화하여 보관하고 있는 객체

- Memento() : 내부정보가 세팅되면 변경 불가하게끔 설정

메멘토 패턴 적용전

public class Game implements Serializable {
 
    private int redTeamScore;
 
    private int blueTeamScore;
 
    public int getRedTeamScore() {
        return redTeamScore;
    }
 
    public void setRedTeamScore(int redTeamScore) {
        this.redTeamScore = redTeamScore;
    }
 
    public int getBlueTeamScore() {
        return blueTeamScore;
    }
 
    public void setBlueTeamScore(int blueTeamScore) {
        this.blueTeamScore = blueTeamScore;
    }
}
public class Client {
 
    public static void main(String[] args) {
        Game game = new Game();
        game.setRedTeamScore(10);
        game.setBlueTeamScore(20);
 
        int blueTeamScore = game.getBlueTeamScore();
        int redTeamScore = game.getRedTeamScore();
 
        Game restoredGame = new Game();
        restoredGame.setBlueTeamScore(blueTeamScore);
        restoredGame.setRedTeamScore(redTeamScore);
    }
}

문제점

- 클라이언트가 게임의 내부정보를 모두 알고 있어야함

- Game의 내부정보를 변경될 때마다 Client에 속해있는 Game의 디테일한 내역을 변경해줘야 한다.

메멘토 패턴 적용후

//Memento
public final class GameSave {
 
    //저장된 정보 그대로 보관하고 있어야하기 때문에 final변수 사용
    private final int blueTeamScore;
 
    private final int redTeamScore;
 
    public GameSave(int blueTeamScore, int redTeamScore) {
        this.blueTeamScore = blueTeamScore;
        this.redTeamScore = redTeamScore;
    }
 
    public int getBlueTeamScore() {
        return blueTeamScore;
    }
 
    public int getRedTeamScore() {
        return redTeamScore;
    }
}
//Originator
public class Game {
 
    private int redTeamScore;
 
    private int blueTeamScore;
 
    public int getRedTeamScore() {
        return redTeamScore;
    }
 
    public void setRedTeamScore(int redTeamScore) {
        this.redTeamScore = redTeamScore;
    }
 
    public int getBlueTeamScore() {
        return blueTeamScore;
    }
 
    public void setBlueTeamScore(int blueTeamScore) {
        this.blueTeamScore = blueTeamScore;
    }
 
    //Game 내부정보를 추상화하는 기능
    public GameSave save() {
        return new GameSave(this.blueTeamScore, this.redTeamScore);
    }
    //Game 내부정보를 복원하는 기능
    public void restore(GameSave gameSave) {
        this.blueTeamScore = gameSave.getBlueTeamScore();
        this.redTeamScore = gameSave.getRedTeamScore();
    }
 
}
//CareTaker
public class Client {
 
    public static void main(String[] args) {
        Game game = new Game();
        game.setBlueTeamScore(10);
        game.setRedTeamScore(20);
 
        GameSave save = game.save();
 
        game.setBlueTeamScore(12);
        game.setRedTeamScore(22);
 
        game.restore(save);
 
        System.out.println(game.getBlueTeamScore());
        System.out.println(game.getRedTeamScore());
    }
}

특징

- Game의 디테일을 알지 않아도 게임의 내부정보를 저장했다가 복원되게 할 수 있다.

장점

- 캡슐화를 지키면서 상태 객체의 상태 스냅샷을 만들 수 있다.

- 객체 상태를 저장하고 또는 복원하는 역할을 Care Taker에게 위임할 수 있다.

- 객체 상태가 바뀌어도 클라이언트 코드는 바뀌지 않는다.

단점

- 많은 정보를 저장하는 Mementor를 자주 생성하는 경우 메모리 사용량에 많은 영향을 줄 수 있다.

실무사용예

Java

- 객체 직렬화, java.io.Serializable

- java.util.Date

728x90

'이론 > GoF' 카테고리의 다른 글

[행동패턴] 전략패턴  (5) 2023.08.23
[행동패턴] 비지터 패턴  (0) 2023.08.22
[행동패턴] 중재자 패턴  (0) 2023.08.17
[행동패턴] 이터레이터 패턴  (0) 2023.08.16
[행동패턴] 인터프리터 패턴  (0) 2023.08.15