备忘录模式

来源:互联网 发布:国产数据库怎么样 编辑:程序博客网 时间:2024/06/06 08:59

备忘录模式常用来在那些对象经常回滚到以前的某个状态的时候使用,在平常情况下,我们为了能够将某个能修改的对象回滚到以前的某个状态的时候,一般会新new一个对象,然后将需要保存对象的内部属性转移到新new的这个对象当中,例如 我要保存游戏角色的当前血量 和 当前的位置。

class Player {

int hp;

int position_x;

int Position_y;

String name;

....省略set get 还有构造方法

}

然后写一个保存的测试方法

public class Test{

public static void main(){

Player play = new Player();

play.setHp(200);

play.setName("我是角色");

play.setPosition_x(20);

play.setPosition_Y(30);

//然后新建一个对象来保存当前的信息

  Player forSavePlayer = new Player();

forSavePlayer.setHp(play.getHp());

forSavePlayer.setPosition_y(play.getPosition_y())

forSavePlayer.setPosition_x(play.getPosition_x);

//假设在下面的一段代码中 play内部的状态发生了改变

.....使play状态发生改变的代码

//现在我们想将play回滚到我们之前保存的那个状态中去

play.setHp(forSavePlayer .getHp());

play.setPosition_x(forSavePlayer .getPosition_x());

play.setPosition_y(forSavePlayer .getPosition_y());

}

}

这样就实现了对象状态的保存,但是这有很多问题  1,就是 如果我们再想保存一个状态,还需要重复new 对象 然后set  get这些方法,当然这可以我们可以通过将其封装到一个方法中,来避免代码的重复  2就是我们new的一个对象 其中有很多属性  是我们不需要保存的,也就是说 我们向jvm虚拟机申请了超出我们实际需要的内存,这个就算我们将其封装成一个方法也是不可以避免的,3 我们如果还要保存角色的名字,这样对代码的改动会比较大。下面我们用备忘录模式来修改一下。

首先新见一个备忘录类

class  MementoPlayer{

int position_x;

int position_y;

int hp; //将我们需要保存的Player的内容声明成类的内部属性,需要保存哪些就声明哪些

public static MementoPlayersaveMemento(Player player){

MementoPlayer mementoPlayer = newMementoPlayer();

mementoPlayer.position_x = player.getPosition_x();

mementoPlayer.position_y=player.getPosition_y ();

mementoPlayer.hp = player.getHp();

returnmementoPlayer;

}

//....同样省略set get方法

}

然后在Player原有的代码当中新加一个方法

public void    resetMementoPlayer(MementoPlayer savePlayer){

this.hp = savePlayer.getHp();

this.position_y = savePlayer.getPosition_y();

this.postion_x = savePlayer.getPosition_x();

}

  最好我们新建一个test类 来验证
  class Test{
public static void main(Strings  args){

Player play = new Player();

play.setHp(200);

play.setName("我是角色");

play.setPosition_x(20);

play.setPosition_Y(30);

//然后新建一个对象来保存当前的信息

 MementoPlayer mentoPlayer = MementoPlayer.saveMemento(play);

//假设在下面的一段代码中 play内部的状态发生了改变

.....使play状态发生改变的代码

//现在我们想将play回滚到我们之前保存的那个状态中去

play.resetMementoPlayer(mentoPlayer);

}
}
  这样就简单的改好了 但是如果我们需要保存多个状态的话,这样做还是不好管理,此时我们可以对其进行进一步的改进 
  在Player 方法中新加一个属性
  Map<String,MementoPlayer> mementoPlayerMap = new HashMap();
  并且加上2个方法
  public void saveMementoPlayer(String mementoPlayerName,MementoPlayer mementoPlayer){
if(mementoPlayerName != null &&  mementoPlayer != null)
mementoPlayerMap.put(mementoPlayerName,mementoPlayer);
else
//抛出异常
}
 
  public void resetSaveZhuangtai(String mementoPlayerName){
if(mementoPlayerMap.get(mementoPlayerName)!= null){
resetMementoPlayer(mementoPlayerMap.get(mementoPlayerName));
}else{
//抛出相应的异常
}
}
这样我们就可以保存多次状态了 并且可以选择性回滚。
测试例子如下
class Test{
public static void main(String[] args){

Player play = new Player();

play.setHp(200);

play.setName("我是角色");

play.setPosition_x(20);

play.setPosition_Y(30);

//然后新建一个对象来保存当前的信息

  play.saveMementoPlayer("测试保存1",MementoPlayer.saveMemento(play));

//假设在下面的一段代码中 play内部的状态发生了改变

.....使play状态发生改变的代码

play.saveMementoPlayer("测试保存2",MementoPlayer.saveMemento(play));

//现在我们想将play回滚到我们测试保存1那个状态中去

play.resetSaveZhuangtai("测试保存1");

}
}

原创粉丝点击