备忘录模式,在工作代码中,要么不用,要么经常用到。
举个例子,程序员喜欢写代码,coding,coding,这个时候它的状态是很high,但是每隔一段时间总要去上一下厕所,状态是放松relax,上完测试归来后又恢复到high的状态,继续coding。这个过程对于身后的老板来说,它默认同意你离开去上厕所,他也希望你回来后恢复high的状态继续工作,但是你在这个过程中上厕所的这件事,他是不需要了解细节的,而且做为当事人你也不希望他了解你上厕所的细节吧,你只要回来后恢复激情high着继续工作,老板应该就不会挑你的刺。
这就是备忘录模式。
本文今天就Canvas的一个save(),restore()操作分析一下,但是有一点,看完本文,如果不懂备忘录模式的,应该还是不懂,但是canvas是android的一场大戏,说一说它的特色,对深入学习android绝对有帮助。
学习备忘录模式,通过保存状态,恢复状态的内部实现,对了解一些莫名其妙的看上去无用其实很重要的操作有拨开云雾见青天的作用。
1.意图
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以将该对象恢复到先前保存的状态。
热门词汇:标记 状态 备忘录 原发器
2.结构和代码
组织者,把原发器的状态State(全部或者部分状态,一般是变量的值),通过CreateMemento()方法保存起来,继续运行后,等待合适的时机,在通过SetMemento()方法可以再次恢复到之前的状态。在这个过程中,我们并没有对这些状态做任何的访问和设置,实际上这些状态都是私有的,对外是禁止访问的,我们只是通过Memento对象的两个最简单的方法就达到了这个效果。Memento经常写成Originator的内部类。
在Android中,Canvas有两个方法 save()和restore()方法再做图形变换的时候使用的非常多,因为涉及到跨语言的问题,我不好就认定这个用的是备忘录模式,但是它的这种思想绝对是备忘录的思想。
我们来读一读它源代码的注释吧,首先看save()保存状态:
public class Canvas { /** * Saves the current matrix and clip onto a private stack. Subsequent * calls to translate,scale,rotate,skew,concat or clip Rect,clipPath * will all operate as usual, but when the balancing call to restore() * is made, those calls will be forgotten, and the settings that existed * before the save() will be reinstated. */ /** *保存当前的矩阵和剪裁到一个私有的堆栈,其实矩阵和剪裁就是当前Canvas的状态State */ public native int save(); }
再看恢复状态restore():
public class Canvas { /** * This call balances a previous call to save(), and is used to remove all * modifications to the matrix/clip state since the last save call. It is * an error to call restore() more times than save() was called. */ /** * 移除自上次保存操作后所做的修改,恢复到之前的状态,因为是堆栈实现,所以pull操作不能不等于push操作,save()和restore()应该成对使用,否则恢复的状态就很有可能是错误的 */ public native void restore(); }
从上面的两个方法中,它们实现了自我状态的恢复,实际上我们只是执行了两个没有接触任何内部信息的方法,实际上这两个方法就是在操作我们看不到的这些内部状态信息。
3.效果
(1).保持封装边界,把很复杂的原发器的内部信息对外部其他对象隐藏起来。
(2).简化的原发器,把状态操作无形中转化到客户手里,简化了原发器的某些实现。
(3).也要注意注意备忘录的管理代价。