备忘录模式(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样就可以将该对象回复到原先保存的状态。
UML图:
月光宝盒的故事
package com.thpin.repository.designpattern;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class MomentoDemo {
public static void main(String[] args) {
MomentPerson boy = new MomentPerson("小明");
MomentPerson girl = new MomentPerson("小红");
boy.setLover(girl);
Originator originator = new Originator(boy, girl);
System.out.println(originator);
Caretaker caretaker = new Caretaker();
caretaker.setMemento(originator.createMomento());
MomentPerson otherBoy = new MomentPerson("小王");
otherBoy.setLover(girl);
originator.getGirl().setLover(otherBoy);
originator.yearsLater(5);
otherBoy.setSpouse(girl);
originator.getGirl().setSpouse(otherBoy);
originator.yearsLater(5);
originator.getGirl().setLover(boy);
originator.setMomento(caretaker.getMemento());
originator.yearsLater(-10);
boy = originator.getGirl();
girl = originator.getBoy();
System.out.println("小明表白小红");
girl.setLover(boy);
boy.setLover(girl);
originator.yearsLater(1);
girl.setSpouse(boy);
boy.setSpouse(girl);
originator.yearsLater(10);
}
}
/*
* 发起人
*/
class Originator {
private MomentPerson boy;
private MomentPerson girl;
public Originator(MomentPerson boy, MomentPerson girl) {
this.boy = boy;
this.girl = girl;
}
// 月光宝盒存入场景
public Memento createMomento() {
Memento memento = null;
try {// 原型模式的深克隆,因为这boy 和 girl 是引用类型
memento = new Memento(boy.deepClone(), girl.deepClone());
} catch (Exception e) {
e.printStackTrace();
}
return memento;
}
// 波若波若蜜,打开月光宝盒
public void setMomento(Memento memento) {
this.boy = memento.getBoy();
this.girl = memento.getGirl();
}
public void yearsLater(int years) {
System.out.println(years + "年...");
System.out.println(this);
}
public MomentPerson getBoy() {
return boy;
}
public void setBoy(MomentPerson boy) {
this.boy = boy;
}
public MomentPerson getGirl() {
return girl;
}
public void setGirl(MomentPerson girl) {
this.girl = girl;
}
@Override
public String toString() {
return "Originator [boy=" + boy + ", girl=" + girl + "]";
}
}
/*
* 月光宝盒,也叫备忘录 它的属性只有getter没有setter 备忘录只读,不能修改
*/
class Memento {
private MomentPerson boy;
private MomentPerson girl;
public Memento(MomentPerson boy, MomentPerson girl) {
this.boy = boy;
this.girl = girl;
}
public MomentPerson getBoy() {
return boy;
}
public MomentPerson getGirl() {
return girl;
}
@Override
public String toString() {
return "Memento [boy=" + boy + ", girl=" + girl + "]";
}
}
class Caretaker {
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
/*
* 当下之人,痴情的人儿
*/
class MomentPerson implements Serializable {
private static final long serialVersionUID = -5993073159780881284L;
private String name;
private MomentPerson lover;
private MomentPerson spouse;
public MomentPerson(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public MomentPerson getLover() {
return lover;
}
public void setLover(MomentPerson lover) {
if (spouse != null)
System.out.println("不可能了,本人已结婚...");
else
this.lover = lover;
}
public MomentPerson getSpouse() {
return spouse;
}
public void setSpouse(MomentPerson spouse) {
setLover(null);
this.spouse = spouse;
}
// 深克隆
public MomentPerson deepClone() throws Exception {
// 将对象写入流中
ByteArrayOutputStream bao = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bao);
oos.writeObject(this);
// 将对象从流中取出
ByteArrayInputStream bis = new ByteArrayInputStream(bao.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (MomentPerson) ois.readObject();
}
@Override
public String toString() {
return "MomentPerson [name=" + name + ", lover=" + (lover != null ? lover.getName() : null) + ", spouse="
+ (spouse != null ? spouse.getName() : null) + "]";
}
}
结果:
Originator [boy=MomentPerson [name=小明, lover=小红, spouse=null], girl=MomentPerson [name=小红, lover=null, spouse=null]]
5年...
Originator [boy=MomentPerson [name=小明, lover=小红, spouse=null], girl=MomentPerson [name=小红, lover=小王, spouse=null]]
5年...
Originator [boy=MomentPerson [name=小明, lover=小红, spouse=null], girl=MomentPerson [name=小红, lover=null, spouse=小王]]
不可能了,本人已结婚...
-10年...
Originator [boy=MomentPerson [name=小明, lover=小红, spouse=null], girl=MomentPerson [name=小红, lover=null, spouse=null]]
小明表白小红
1年...
Originator [boy=MomentPerson [name=小明, lover=小红, spouse=null], girl=MomentPerson [name=小红, lover=小明, spouse=null]]
10年...
Originator [boy=MomentPerson [name=小明, lover=null, spouse=小红], girl=MomentPerson [name=小红, lover=null, spouse=小明]]
曾经有一份真挚的爱情放在我面前,我没有去珍惜,直到失去后我才追悔莫及。人生中最痛苦的事莫过于此,如果一切可以重来,我会对那个女孩说:我爱你!如果要我在这份爱上加上一个期限——那会是一万年!
使用备忘录的时候别忘记对象的备份是消耗内存的。
程序里你可以使用备忘录保存重要的状态,大话西游里至尊宝可以使用月光宝盒回到过去。毕竟这些都是假的!人生不复返珍惜眼前人,或许身边那个人才值得你拥有。