디자인패턴

메멘토 패턴(Memento Pattern)

JUNGKEUNG 2022. 10. 8. 18:33
반응형

메멘토 패턴이란?

객체의 상태 정보를 저장하고 사용자의 필요에 의하여 원하는 시점의 데이터를 복원 할 수 있는 패턴을 말한다.

 

 

 

 

구조

  • Originator : 우리가 저장할 객체이다. 즉 originator의 state를 저장할 것이다
  • Care Taker : originator의 내부 정보를 Care Taker가 가져와서 저장한다
  • Memento : 내부정보를 추상화한 클래스. Care Taker는 Originator의 디테일한 정보를 직접적으로 가지는 것이 아니라 memento타입으로 가진다. 

 

예제 코드

만약 게임을 하는데. 게임을 중지시켰다가 다시 실행해도 중지 전까지 스코어는 유지되어야 한다. 

@Getter
@Setter
public class Game {
	private int redTeamScore;
    private int blueTeamScore;
}
public class Client {
	public static void main(String[] args) {
    	Game game = new Game();
        game.setRedTeamScore(10);
        game.setRedTeamScore(20);
        
        int blueTeamScore = game.getBlueTeamScore();
        int RedTeamScore = game.getRedTeamScore();
        
        Game restoredGame = new Game();
        restoredGame.setBlueTeamScore(blueTeamScore);
        restoredGame.setRedTeamScore(redTeamScore);
        // 클라이언트가 게임 내에 필드 정보들을 일일이 알야아 한다.
    }
}

초반에 red팀의 score는 10, blue팀의 score는 20이다. 이러한 정보를 각각 redTeamScore, blueTeam Score에 저장해두고 아래에서 새로 생성된 Game객체의 score정보에 set해준다.

 

문제점

위의 Client가 하나하나 Game의 score에 대해 알고 있어야 한다. 이를 메멘토 패턴에 적용하여 해결하자

먼저 Memento인 GameSave를 보자

@Getter
/*Memento*/
public final class GameSave {
	/*final 키워드를 불변하도록 한다.*/
    private final int redTeamScore;
    private final int BlueTeamScore;
    
    public GameSave(int redTeamScore, int blueTeamScore) {
    	this.redTeamScore = redTeamScore;
        this.blueTeamScore = blueTeamScore;
    }
	/*setter는 불변하게 하기 위해 없다*/
}
  • Memento는 GameSave가 가지고 있는 필드를 모두 가지고 있다. 즉, 불변객체이다. score정보들은 한 번 생성자를 통해 한번 생성되면 절대 변하지 않는다
  • Originator인 Game은 이전과 같지만, Game의 상태를 GameSave에 저장하는 save메소드와 Game Save로 부터 이전의 상태를 되돌리는 restore메소드가 추가된다.
@Getter @Setter
/* Originator*/
public class Game {
	private int redTeamScore;
    private int blueTeamScore;
    
    /*현재 상태 저장*/
    public GameSave save() {
    	return new GameSave(this.redTeamScore, this.blueTeamScore);
    }
    
    /*이전 상태 복구*/
    public void restore(GameSave gameSave) {
    	this.redTeamScore = gameSave.getRedTeamScore();
        this.blueTeamScore = gameSave.getBlueTeamScore();
    }
}

Client는 아래와 같다. 이제 직접적으로 Game의 score에 대한 정보를 알 필요 없이 GameSave(Memento)에 요청한다

 

public class Clinet {
	public static void main(String[] args) {
    
        Game game = new Game();
        /*게임 초반의 상태*/
        game.setBlueTeamScore(10);
        game.setBlueTeamScore(20);

        /*게임의 state 정보를 GameSave에 저장( 여기서 Client는 CateTaker가 된다. )*/
        GameSave memento = game.save();

        /* game의 정보 수정*/
        game.setRedTeamScore(12);
        game.setBlueTeamScore(22);

        /* game을 memento에 저장된 정보로 restore */
        game.restore(memento);
        System.out.println(game.getBlueTeamScore());
        System.out.println(game.getRedTeamScore());
    }
}

 

 

장점

  • 저장된 상태를 핵심 객체와는 다른 별도의 객체에 보관하기 때문에 안전하다
  • 핵심 객체에 데이터를 계속해서 캡슐화된 상태로 유지할 수 있다
  • 복구 기능을 구현하기 쉽다

 

 

단점

  • 이전 상태의 객체를 저장하기 위한 Originator가 클 경우 많은 메모리가 필요하다
  • 상태를 저장하고 복구하는 데 시간이 오래 걸리 수 있다
  • 자바 시스템에서는 상태를 저장할 때 직렬화를 사용하는 것이 좋다

 

Script


객체의 상태 정보를 저장하고 사용자의 필요에 의하여 원하는 시점의 데이터를 복원 할 수 있는 패턴을 말한다.

 

 

참고


 

 

코딩으로 학습하는 GoF의 디자인 패턴 - 인프런 | 강의

디자인 패턴을 알고 있다면 스프링 뿐 아니라 여러 다양한 기술 및 프로그래밍 언어도 보다 쉽게 학습할 수 있습니다. 또한, 보다 유연하고 재사용성이 뛰어난 객체 지향 소프트웨어를 개발할

www.inflearn.com