2014-12-15 5 views
0

Java에서 Memento pattern의 구현을 구현하려고했습니다.메멘토 패턴이 올바르게 작동하지 않습니다.

예제는 사용자가 F5을 누르면 게이머 상태 =>F9을 마지막으로 저장 한 게이머 상태를 복구 한 후 쉽게 복사 할 수 있습니다. 여기

쉽게 실행에서 출력 :

Health:   100 
Killed Monsters: 0 
Health:   90 
Killed Monsters: 2 
Health:   81 
Killed Monsters: 4 
Health:   72 
Killed Monsters: 6 
Health:   64 
Killed Monsters: 8 
Health:   57 
Killed Monsters: 10 

그러나 지난 2 개 라인이 있어야한다 있기 때문에, 잘못된 결과 :

Health:   90 
Killed Monsters: 2 

내가 잘못이 무엇인지 알아낼 수 없었다. 코드는 괜찮아 보입니다.

import java.util.Stack; 

class GameState { 
    private int health; 
    private int killedMonsters; 

    public GameState(int health, int killedMonsters) { 
     this.health = health; 
     this.killedMonsters = killedMonsters; 
    } 

    public double getHealth() { 
     return health; 
    } 

    public int getKilledMonsters() { 
     return killedMonsters; 
    } 

    public void setHealth(int health) { 
     this.health = health; 
    } 

    public void setKilledMonsters(int killedMonsters) { 
     this.killedMonsters = killedMonsters; 
    } 

    @Override 
    public String toString() { 
     return String.format("Health: %1$12d\nKilled Monsters: %2$3d", health, killedMonsters); 
    } 
} 

class GameMemento { 
    private GameState gameState; 

    public GameMemento(GameState gameState) { 
     this.gameState = gameState; 
    } 

    public GameState getGameState() { 
     return gameState; 
    } 
} 

class GameOriginator { 
    private GameState gameState = new GameState(100, 0); 

    public void play() { 
     System.out.println(gameState.toString()); 
     gameState.setHealth((int)(gameState.getHealth() * 0.9)); 
     gameState.setKilledMonsters(gameState.getKilledMonsters() + 2); 
    } 

    public GameMemento saveGame() { 
     return new GameMemento(gameState); 
    } 

    public void loadGame(GameMemento memento) { 
     gameState = memento.getGameState(); 
    } 
} 

class Caretacker { 
    private GameOriginator game = new GameOriginator(); 
    private Stack<GameMemento> quickSaves = new Stack<>(); 

    public void shutThisDumbAss() { 
     game.play(); 
    } 

    public void F5() { 
     quickSaves.push(game.saveGame()); 
    } 

    public void F9() { 
     game.loadGame(quickSaves.peek()); 
    } 
} 

public class MementoDemo { 
    public static void main(String[] args) { 
     Caretacker caretacker = new Caretacker(); 
     caretacker.F5(); 
     caretacker.shutThisDumbAss(); 
     caretacker.F5(); 
     caretacker.shutThisDumbAss(); 
     caretacker.shutThisDumbAss(); 
     caretacker.shutThisDumbAss(); 
     caretacker.shutThisDumbAss(); 
     caretacker.F9(); 
     caretacker.shutThisDumbAss(); 
    } 
} 

어떤 제안 : 여기

는 코드인가?

답변

1

GameMemento 개체에서 동일한 GameState 참조를 다시 사용하고있는 것이 문제입니다. 따라서 GameState 개체의 속성을 변경하면 GameMemento에 저장된 개체도 변경됩니다.

public GameMemento saveGame() { 
    return new GameMemento(new GameState(gameState.getHealth(), gameState.getKilledMonsters())); 
} 

당신은 또한 현재의 인스턴스를 복사 할 clone 방법을 사용할 수 있습니다 :이 문제를 해결하려면

대신 원래의 참고 문헌 GameState 객체의 복사본을 저장 아래의 예와 같이 코드를 변경하는 것이 필요하다 GameState.

1

스택에 동일한 GameOriginator 객체에 대한 참조가 있습니다. 방어 복사본을 나중에 회수하기 위해 방어 복사본을 저장합니다.

public GameMemento saveGame() { 
return new GameMemento(new GameState(gameState.getHealth(), gameState.getKilledMonsters())); 
} 
관련 문제