客户端承担了太多的职责,保存对象内部状态的操作都是由客户端操作显然是不合理的.一般来说客户端MainClass的main方法里面的功能都不会很麻烦.如果Person类的内部增加了一个属性或者状态,客户端的main方法里面也要做相应的修改.客户端里面直接调用对象的方法都不会很多.
public class MainClass { public static void main(String[] args) { Person per = new Person("lifengxing","男",30); //保存内部状态 Person backup = new Person();//备份 backup.setName(per.getName()); backup.setAge(per.getAge()); backup.setSex(per.getSex()); per.display(); //修改 per.setAge(20); per.display(); //回滚 还原 per.setName(backup.getName()); per.setSex(backup.getSex()); per.setAge(backup.getAge()); per.display(); } }
public class Person { //姓名 private String name; //性别 private String sex; //年龄 private int age; public Person(String name, String sex, int age) { super(); this.name = name; this.sex = sex; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Person() { super(); // TODO Auto-generated constructor stub } public void display(){ System.out.println("name:" + name + ",sex:" + sex + ",age:" +age ); } }
Originator:Person
Memento:是简化的Person类.但是Memento是必不可少的,因为它和Originator担纲的是不同的角色.它的状态和Originator的状态是一样的,都是name,sex和age.
备忘录模式不用通过客户端保存Originator的状态,
备忘录设计模式的结构图是一个类图,Caretaker持有了Memento的一个引用,一个箭头加一个菱形是聚合.Caretaker包含了Memento,Caretaker持有了Memento的一个引用.
Caretaker是一个管理者,Caretaker持有了Memento的一个引用所以可以从Caretaker里面取出Memento.把Memento设置到Caretaker里面去了.
使用Caretaker的好处是对我们客户端而言,把Memento设置到Caretaker里面,要拿的时候就从Caretaker里面去拿.
这样类这一部分的责任就非常清晰了,单一责任.被保存者里面包含了备忘录的创建以及备忘录的还原.Memento是三个类中最简单的,它就保存了被保存者的状态.
Caretaker持有了这些状态的引用,可以用setter/getter方法获得Memento.
《大话设计模式》引用了一个例子描述备忘录模式.游戏闯关.保存游戏的状态随时还原过来.
package com.ibeifeng.ex2; public class Caretaker { private Memento memento; public Memento getMemento() { return memento; } public void setMemento(Memento memento) { this.memento = memento; } }
package com.ibeifeng.ex2; public class MainClass { public static void main(String[] args) { Person per = new Person("lifengxing","男",24); //Memento memento = per.createMemento(); Caretaker caretaker = new Caretaker();//创建一个管理者 caretaker.setMemento(per.createMemento()); per.display();//修改前 per.setName("beifeng"); per.setSex("女"); per.setAge(1); per.display();//修改后 //per.setMemento(memento); per.setMemento(caretaker.getMemento()); per.display();//恢复 } }
package com.ibeifeng.ex2; public class Memento { //姓名 private String name; //性别 private String sex; //年龄 private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Memento(String name, String sex, int age) { super(); this.name = name; this.sex = sex; this.age = age; } }
package com.ibeifeng.ex2; public class Person { //姓名 private String name; //性别 private String sex; //年龄 private int age; public Person(String name, String sex, int age) { super(); this.name = name; this.sex = sex; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Person() { super(); // TODO Auto-generated constructor stub } public void display(){ System.out.println("name:" + name + ",sex:" + sex + ",age:" +age ); } //创建一个备份. //创建你当前状态的备份. public Memento createMemento(){ return new Memento(name,sex,age); } //恢复备份. public void setMemento(Memento memento){ this.name = memento.getName(); this.age = memento.getAge(); this.sex = memento.getSex(); } }