1、定义:
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
2、功能:
2.1、当角色的状态改变时,有可能这个状态无效,这时候就可以使用暂存起来的备忘录将状态复原。
2.2、实现命令的撤销功能。命令模式可以使用备忘录来存储可撤销操作的状态。
3、适用场景:
Memento模式适用于:功能比较复杂的,需要维护或记录属性历史的类 or 需要保存的属性只是众多属性中的一小部分时,Originator可以根据保存的Memento信息还原到前一状态。
4、缺点:
如果Memento存储到信息量比较大,则会非常消耗内存。
5、UML图
6、例子
6.1、场景:
某个游戏角色a有3个属性:生命力、攻击力、防御力。在角色a攻击角色b之前,这三个属性是一个状态值;攻击完b后,这三个属性值是另一个状态值;此时借助角色存储备忘录Memento,恢复a攻击前的状态值。
6.2、UML图:
6.3、code:
先给出代码结构图,然后给出代码
package designmodel.eighteenthchapter;
/**
* @Author: cxh
* @CreateTime: 18/1/16 09:26
* @ProjectName: JavaBaseTest
*/
public class CareTaker{
private RoleStateMemento memento;
CareTaker(RoleStateMemento memento){
this.memento=memento;
}
//get
public RoleStateMemento getMemento() {
return memento;
}
}
package designmodel.eighteenthchapter;
/**
* @Author: cxh
* @CreateTime: 18/1/16 09:38
* @ProjectName: JavaBaseTest
*/
public class Client {
public static void main(String[] args) {
GameRole role=new GameRole(11,22,33);
//攻击前状态
role.beforeAttack();
//保存状态
RoleStateMemento memento=role.getMemento();
CareTaker careTaker=new CareTaker(memento);
//攻击后状态
role.afterAttack();
//恢复后状态
role.recover(careTaker);
}
}
package designmodel.eighteenthchapter;
/**
* @Author: cxh
* @CreateTime: 18/1/16 09:12
* @ProjectName: JavaBaseTest
*/
public class GameRole {
private int lifeLenth;
private int attackLength;
private int defendLength;
GameRole(int life,int attack,int defend){
this.lifeLenth=life;
this.attackLength=attack;
this.defendLength=defend;
}
//保存状态
public RoleStateMemento getMemento(){
return new RoleStateMemento(lifeLenth,attackLength,defendLength);
}
//攻击前状态
public void beforeAttack(){
printState("攻击前");
}
//攻击后状态
public void afterAttack(){
this.lifeLenth=0;
this.attackLength=0;
this.defendLength=0;
printState("攻击后");
}
//恢复状态
public void recover(CareTaker careTaker){
this.lifeLenth=careTaker.getMemento().getLifeLen();
this.attackLength=careTaker.getMemento().getAttackLen();
this.defendLength=careTaker.getMemento().getDefendLen();
printState("恢复后");
}
//输出当前状态
private void printState(String time){
System.out.println(time+"状态: 生命力"+lifeLenth+",攻击力"+attackLength+",防守力"+defendLength);
}
}
package designmodel.eighteenthchapter;
/**
* @Author: cxh
* @CreateTime: 18/1/16 09:15
* @ProjectName: JavaBaseTest
*/
public class RoleStateMemento{
private int lifeLen;
private int attackLen;
private int defendLen;
RoleStateMemento(int life,int attack,int defend){
this.lifeLen=life;
this.attackLen=attack;
this.defendLen=defend;
}
//get
public int getLifeLen() {
return lifeLen;
}
public int getAttackLen() {
return attackLen;
}
public int getDefendLen() {
return defendLen;
}
}