定义(源于GoF《设计模式》):在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
备忘录模式,在工作代码中,要么不用,要么经常用到。
以保存游戏进度为例,在游戏角色大战Boss前将该角色的状态存储,与Boss作战后角色的各项能力会下降,如果没有通关,则可利用备忘录进行恢复到战前状态。
游戏角色类:
package com.zyh.designpattern.memento;
public class PlayRole {
private int vitality;
private int aggressivity;
private int defencivity;
public PlayRole(int vitality, int aggressivity, int defencivity) {
super();
this.vitality = vitality;
this.aggressivity = aggressivity;
this.defencivity = defencivity;
}
public PlayRole() {
}
public int getVitality() {
return vitality;
}
public void setVitality(int vitality) {
this.vitality = vitality;
}
public int getAggressivity() {
return aggressivity;
}
public void setAggressivity(int aggressivity) {
this.aggressivity = aggressivity;
}
public int getDefencivity() {
return defencivity;
}
public void setDefencivity(int defencivity) {
this.defencivity = defencivity;
}
public RoleMemento createMemento() {
RoleMemento memento = new RoleMemento();
memento.setAggressivity(aggressivity);
memento.setDefencivity(defencivity);
memento.setVitality(vitality);
return memento;
}
public void setMemento(RoleMemento memento) {
this.aggressivity = memento.getAggressivity();
this.defencivity = memento.getDefencivity();
this.vitality = memento.getVitality();
}
public void showState() {
System.out.println("攻击力:" + this.aggressivity + "|防御力:"
+ this.defencivity + "|生命力:" + this.vitality);
}
}
备忘录类:
package com.zyh.designpattern.memento;
public class RoleMemento {
private int vitality;
private int aggressivity;
private int defencivity;
public int getVitality() {
return vitality;
}
public void setVitality(int vitality) {
this.vitality = vitality;
}
public int getAggressivity() {
return aggressivity;
}
public void setAggressivity(int aggressivity) {
this.aggressivity = aggressivity;
}
public int getDefencivity() {
return defencivity;
}
public void setDefencivity(int defencivity) {
this.defencivity = defencivity;
}
}
管理者类:
package com.zyh.designpattern.memento;
public class Caretaker {
RoleMemento memento;
public RoleMemento getMemento() {
return memento;
}
public void setMemento(RoleMemento memento) {
this.memento = memento;
}
}
客户端:
package com.zyh.designpattern.memento;
public class Client {
public static void main(String[] args) {
// 测试程序
// 新建角色
PlayRole role = new PlayRole(100, 100, 100);
// 新建管理者
Caretaker taker = new Caretaker();
// 角色初始状态
System.out.println("游戏刚开始,角色各属性:");
role.showState();
// 利用备忘录模式保存当前状态
System.out.println("\n【保存游戏状态!】\n");
taker.setMemento(role.createMemento());
role.setAggressivity(20);
role.setDefencivity(30);
role.setVitality(0);
// 大战过后,角色能力值下降
System.out.println("与Boss对战后,角色各项能力已大大下降:");
role.showState();
// 恢复保存的角色状态
role.setMemento(taker.getMemento());
System.out.println("\n【恢复保存的角色状态!】");
System.out.println("\n恢复后角色的当前状态:");
role.showState();
}
}
本文今天就Canvas的一个save(),restore()操作分析一下,但是有一点,看完本文,如果不懂备忘录模式的,应该还是不懂,但是canvas是android的一场大戏,说一说它的特色,对深入学习android绝对有帮助。
学习备忘录模式,通过保存状态,恢复状态的内部实现,对了解一些莫名其妙的看上去无用其实很重要的操作有拨开云雾见青天的作用。
1.意图
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以将该对象恢复到先前保存的状态。
热门词汇:标记 状态 备忘录 原发器
2.结构和代码
组 织者,把原发器的状态State(全部或者部分状态,一般是变量的值),通过CreateMemento()方法保存起来,继续运行后,等待合适的时机, 在通过SetMemento()方法可以再次恢复到之前的状态。在这个过程中,我们并没有对这些状态做任何的访问和设置,实际上这些状态都是私有的,对外 是禁止访问的,我们只是通过Memento对象的两个最简单的方法就达到了这个效果。Memento经常写成Originator的内部类。
在Android中,Canvas有两个方法 save()和restore()方法再做图形变换的时候使用的非常多,因为涉及到跨语言的问题,我不好就认定这个用的是备忘录模式,但是它的这种思想绝对是备忘录的思想。
我们来读一读它源代码的注释吧,首先看save()保存状态:
再看恢复状态restore():
从上面的两个方法中,它们实现了自我状态的恢复,实际上我们只是执行了两个没有接触任何内部信息的方法,实际上这两个方法就是在操作我们看不到的这些内部状态信息。
3.效果
(1).保持封装边界,把很复杂的原发器的内部信息对外部其他对象隐藏起来。
(2).简化的原发器,把状态操作无形中转化到客户手里,简化了原发器的某些实现。
(3).也要注意注意备忘录的管理代价。