大家有没有看过尼古拉斯·凯奇主演的《Next》(中文译名为《预见未来》)?尼古拉斯
·凯奇饰演一个可以预视并且扭转未来的人,其中有一个情节很是让人心动——男女主角见
面的那段情节:Cris Johnson(尼古拉斯·凯奇饰演)坐在咖啡吧台前,看着离自己近在咫尺
的Callie Ferris(朱莉安·摩尔饰演),计划着怎么认识这个命中注定的女人,看Cris Johnson
如何利用自己的特异功能:
● Cris Johnson端着一杯咖啡走过去,说“你好,可以认识你吗?”被拒绝,恢复到坐在咖
啡吧台前的状态。
● 走过去询问是否可以搭车,被拒绝,恢复原状。
● 帮助解决困境,被拒绝,恢复原状。
● 采用嬉皮士的方式解决困境,被拒绝,恢复原状。
● 帮助解决困境,被打伤,装可怜,Callie Ferris怜惜,于是乎相识了。
看看这是一件多么幸福的事情,追求一个女生可以多次反复地实验,直到找到好的方法
和途径为止,这估计是大多数男生都希望获得的特异功能。想想看,看到一个心仪的女生,
我们若反复尝试,总会有一个方法打动她的,多美好的一件事。现在我们还得回到现实生
活,我们来分析一下类似事情的经过:
● 复制一个当前状态,保留下来,这个状态就是等会儿搭讪女孩子失败后要恢复的状
态,你不恢复原始状态,这不就露馅儿了吗?
● 每次试探性尝试失败后,都必须恢复到这个原始状态。
● N次试探总有一次成功吧,成功以后即可走成功路线。
想想看,我们这里的场景中最重要的是哪一块?对的,是原始状态的保留和恢复这块,
如何保留一个原始,如何恢复一个原始状态才是最重要的,那想想看,我们应该怎么实现
呢?很简单呀,我们可以定义一个中间变量,保留这个原始状态。我们先看看类图,如图
package MementoP; public class Boy { private String state = ""; public void changeState(){ this.state = "bad"; } public String getState(){ return state; } public void setState(String state){ this.state = state; } }
package MementoP; public class Client { public static void main(String[] args) { Boy boy = new Boy(); boy.setState("great"); System.out.println(boy.getState()); Boy backup = new Boy(); backup.setState(boy.getState()); boy.changeState(); System.out.println(boy.getState()); boy.setState(backup.getState()); System.out.println(boy.getState()); } }
Boy类封装不够,那我们应该如何修改呢?如果在Boy类中
再增加一个方法或者其他的内部类来保存这个状态,则对单一职责原则是一种破坏,想想看
单一职责原则是怎么说的?一个类的职责应该是单一的,Boy类本身的职责是追求女孩子,
而保留和恢复原始状态则应该由另外一个类来承担,那我们把这个类取名就叫做备忘录,这
和大家经常在桌面上贴的那个便签是一个概念,分析到这里我们的思路已经非常清楚了,我
们来修改一下类图,如图
package MementoP; public class Memento { public String state = ""; public Memento(String state){ this.state = state; } public String getState() { return state; } public void setState(String state) { this.state = state; } }
package MementoP; public class Boy { private String state = ""; public void changeState(){ this.state = "bad"; } public String getState(){ return state; } public void setState(String state){ this.state = state; } public Memento createMemento(){ return new Memento(this.state); } public void restoreMemento(Memento memento){ this.setState(memento.getState()); } }
package MementoP; public class Client { public static void main(String[] args) { /*Boy boy = new Boy(); boy.setState("great"); System.out.println(boy.getState()); Boy backup = new Boy(); backup.setState(boy.getState()); boy.changeState(); System.out.println(boy.getState()); boy.setState(backup.getState()); System.out.println(boy.getState());*/ //声明出主角 Boy boy = new Boy(); //初始化当前状态 boy.setState("心情很棒!"); System.out.println("=====男孩现在的状态======"); System.out.println(boy.getState()); //需要记录下当前状态呀 Memento mem = boy.createMemento(); //男孩去追女孩,状态改变 boy.changeState(); System.out.println("\n=====男孩追女孩子后的状态======"); System.out.println(boy.getState()); //追女孩失败,恢复原状 boy.restoreMemento(mem); System.out.println("\n=====男孩恢复后的状态======"); System.out.println(boy.getState()); } }
备忘录模式(Memento Pattern)提供了一种弥补真实世界缺陷的方法,让“后悔药”在程
序的世界中真实可行,其定义如下:
Without violating encapsulation,capture and externalize an object's internal state so that the
object can be restored to this state later.(在不破坏封装性的前提下,捕获一个对象的内部状
态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。)