14、备忘录模式—月光宝盒,人生不复返珍惜眼前人

备忘录模式(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=小明]]


曾经有一份真挚的爱情放在我面前,我没有去珍惜,直到失去后我才追悔莫及。人生中最痛苦的事莫过于此,如果一切可以重来,我会对那个女孩说:我爱你!如果要我在这份爱上加上一个期限——那会是一万年!

使用备忘录的时候别忘记对象的备份是消耗内存的。

程序里你可以使用备忘录保存重要的状态,大话西游里至尊宝可以使用月光宝盒回到过去。毕竟这些都是假的!人生不复返珍惜眼前人,或许身边那个人才值得你拥有。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值