首页 > 代码库 > 备忘录模式
备忘录模式
备忘录模式,望文生义就知道它是用来做备忘的,或者可以直接说是“备份”。当需要保存当前状态,以便在不久要恢复此状态时,就可以使用“备忘录模式”。将当前”状态“备份,是不是又new一个类,然后将每个字段方法copy过去就可以了呢?或者说使用我们之前clone方法做深复制浅复制呢?其实不然,在《大话设计模式》中,作者提到了原因,这样会暴露更多的细节给客户端,不符合我们面向对象的思想。什么是暴露更多的细节给客户端?我们来看下面一段代码。
1 package day_27_memento; 2 3 /** 4 * @author turbo 5 * 6 * 2016年9月27日 7 */ 8 public class Client { 9 10 /**11 * @param args12 */13 public static void main(String[] args) {14 /*状态一*/15 Test nowTest = new Test();16 nowTest.setField("状态一");17 18 /*备份状态*/19 Test backUpTest = new Test();20 backUpTest.setField(nowTest.getField());21 22 /*修改状态一*/23 nowTest.setField("修改状态一,改为状态二");24 25 /*还原状态*/26 nowTest.setField(backUpTest.getField());27 }28 29 }
Test类中只有一个field字段,不再贴出代码。由上代码我们可以看到,如果要备份的字段较多,在客户端里就会暴露过多的细节。而我们希望的是,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这句话的后面两句是啥意思呢?捕获一个对象的内部状态——值得是要获得需要备份的状态(或者简单理解为字段),该备份状态要保存在另外一个类并要有对象自己来读取。
我们还是先来看代码。在备忘录模式中涉及到三个基本的类,一个是原始类,即需要备份的状态类,一个是备份类,即具体存储状态,还有一个管理者,用来提供备份状态类。
首先实现原始类,在这个类里除去该类本身自有的方法,还要有一个创建备份和获取备份的两个方法。
1 package day_27_memento; 2 3 /** 4 * 发起人,它要负责创建一个备忘录Memento用来记录当前时刻它的状态 5 * @author turbo 6 * 7 * 2016年9月27日 8 */ 9 public class Originator {10 private String state;11 12 public String getState() {13 return state;14 }15 16 public void setState(String state) {17 this.state = state;18 }19 20 /**21 * 显示状态22 */23 public void show(){24 System.out.println("state : " + state);25 }26 27 /**28 * 创建备忘录29 * @return 备份的状态30 */31 public Memento createMemento(){32 return (new Memento(state)); //在这句我们可以看到将状态细节封装在了内部,对外部透明。33 }34 35 /**36 * 获取备份37 * @param memento 备份类38 */39 public void setMememto(Memento memento){40 state = memento.getState();41 }42 }
备忘类。
1 package day_27_memento; 2 3 /** 4 * 备忘类 5 * @author turbo 6 * 7 * 2016年9月27日 8 */ 9 public class Memento {10 private String state;11 12 public String getState() {13 return state;14 }15 16 public Memento(String state){17 this.state = state;18 }19 }
接着来看看这个管理者类。
1 package day_27_memento; 2 3 /** 4 * 管理者 5 * @author turbo 6 * 7 * 2016年9月27日 8 */ 9 public class Caretaker {10 private Memento memento;11 12 public Memento getMemento() {13 return memento;14 }15 16 public void setMemento(Memento memento) {17 this.memento = memento;18 }19 20 }
管理者类就是用来提供备忘录类的。最后我们来看客户端代码。
1 package day_27_memento; 2 3 /** 4 * @author turbo 5 * 6 * 2016年9月27日 7 */ 8 public class Main { 9 public static void main(String[] args){10 /*当前状态*/11 Originator originator = new Originator();12 originator.setState("On");13 originator.show();14 /*备份当前状态*/15 Caretaker caretaker = new Caretaker();16 caretaker.setMemento(originator.createMemento());17 /*更新状态*/18 originator.setState("Off");19 originator.show();20 /*备份状态*/21 originator.setMememto(caretaker.getMemento());22 originator.show();23 }24 }
从代码16行、21行,我们能看到实际上就是书中所说,“有时一些对象的内部信息必须保存在对象以外的地方,但是必须要由对象自己读取”。
备忘录模式
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。