设计模式之备忘录模式
2013-05-26 20:26 youxin 阅读(507) 评论(0) 编辑 收藏 举报为了使软件的使用更加人性化,对于误操作,我们需要提供一种类似“后悔药”的机制,让软件系统可以回到误操作前的状态,因此需要保存用户每一次操作时系统的状态,一旦出现误操作,可以把存储的历史状态取出即可回到之前的状态。
package dp.memento; public class Originator { private String state; public Originator(){} // 创建一个备忘录对象 public Memento createMemento(){ return new Memento(this); } // 根据备忘录对象恢复原发器状态 public void restoreMemento(Memento m){ state = m.state; } public void setState(String state) { this.state=state; } public String getState() { return this.state; } }
package dp.memento; class Memento { private String state; public Memento(Originator o){ state = o.state; } public void setState(String state) { this.state=state; } public String getState() { return this.state; } }
在设计备忘录类时要考虑其封装性,除了originator类,不允许其他类来调用其构造函数与相关方法,如果不考虑其封装性,允许其他类调用setState()等方法,将导致在备忘录中保存的历史状态 发生改变,通过撤销操作所回复的状态就不再是真实的历史状态,备忘录模式也就失去了意义。
在使用java语言实现备忘录模式时,一般通过将Memento类与originator类定义在同一个package中来实现封装,在java中可使用默认访问标识符来定义Memento类,即保证其保内可见性。只有Originator类可以对其进行访问,而限制其他类对Memento的访问,
负责人类:
package dp.memento; public class Caretaker { private Memento memento; public Memento getMemento() { return memento; } public void setMemento(Memento memento) { this.memento=memento; } }
在Caretaker中也不应该直接调用Memento中的状态方法,它的作用仅仅用于存储备忘录对象,。
package demo1.memento; public class UserInfoDTO { private String account; private String password; private String telNo; public Memento createMemento() { return new Memento(this); } public void restoreMemento(Memento memento) { this.account=memento.getAccount(); this.password=memento.getPassword(); this.telNo=memento.getTelNo(); } public void printInfo() { System.out.println("Account:"+this.account); System.out.println("Password:"+this.password); System.out.println("TelNO:"+this.telNo); } public String getAccount() { return account; } public void setAccount(String account) { this.account = account; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getTelNo() { return telNo; } public void setTelNo(String telNo) { this.telNo = telNo; } }
Memento:
package demo1.memento; public class Memento { private String account; private String password; private String telNo; public Memento(UserInfoDTO o) { account=o.getAccount(); password=o.getPassword(); telNo=o.getTelNo(); } public String getAccount() { return account; } public void setAccount(String account) { this.account = account; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getTelNo() { return telNo; } public void setTelNo(String telNo) { this.telNo = telNo; } }
caretaker:
public class Caretaker { private Memento memento; public Memento getMemento() { return this.memento; } public void setMemento(Memento memento) { this.memento=memento; } }
客户端代码:
import demo1.memento.Caretaker; import demo1.memento.UserInfoDTO; public class Client { public static void main(String[] args) { UserInfoDTO o=new UserInfoDTO(); Caretaker c=new Caretaker();//创建负责人 o.setAccount("user1"); o.setPassword("pwd1"); o.setTelNo("tel1"); o.printInfo(); c.setMemento(o.createMemento()); //保存备忘录 System.out.println("-------------------"); o.setAccount("user2"); o.printInfo(); } }
Account:user1
Password:pwd1
TelNO:tel1
-------------------
Account:user2
Password:pwd1
TelNO:tel1
恢复---------------------------
Account:user1
Password:pwd1
TelNO:tel1
为什么我们要创建Caretaker类?参考前面所说的。
不创建Caretaker同样可以操作:
UserInfoDTO o=new UserInfoDTO(); o.setAccount("user1"); o.setPassword("pwd1"); o.setTelNo("tel1"); o.printInfo(); Memento memento=o.createMemento(); System.out.println("改变后:"); o.setAccount("user2"); o.printInfo(); o.restoreMemento(memento); System.out.println("恢复后为:"); o.printInfo();