设计模式之备忘录模式(卷十七)

0x00 概述

备忘录模式提供了一种类似于版本控制的功能,使得用户可以回退到特定的一个版本,常见的undo、redo就是典型的代表。

在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。它是一种对象行为型模式,其别名为Token。

0x01 组成部分

  • Originator:原发器,通常将需要保存内部状态的类设计为原发器,一般设有createMemento()和restoreFromMemento(Memento m)两个方法,前者用于创建一个版本的备忘录对象,后者用于从备忘录中恢复状态。
  • Memento:备忘录,用于存储原发器的内部状态,只允许原发器和负责人访问,不允许其他对象访问。
  • MementoCareTaker,负责人,仅仅用于存储备忘录对象,不允许操作改变备忘录对象状态。

UML架构图如下:

0x10 示例代码

以下代码以undo、redo功能为例。

package com.kkk.pattern.memento;

/**
 * 数学计算公式,充当原发器。
 * Created by z3jjlzt on 2018/2/5.
 */
public class Formula {

    private String state;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    /**
     * 创建一个备忘录。
     * @return
     */
    public Memento createMemento() {
        Memento memento = new Memento();
        memento.setMstate(getState());
        return memento;
    }

    public void restoreFromMemento(Memento memento) {
        this.state = memento.getMstate();
    }

    public Memento op(String state) {
        Memento memento = createMemento();
        this.state = this.state + state;
        return memento;
    }

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("Formula{");
        sb.append("state='").append(state).append('\'');
        sb.append('}');
        return sb.toString();
    }

/**
 * 备忘录类。
 * Created by z3jjlzt on 2018/2/5.
 */
class Memento {
    private String mstate;

    public String getMstate() {
        return mstate;
    }

    public void setMstate(String mstate) {
        this.mstate = mstate;
    }

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("Memento{");
        sb.append("mstate='").append(mstate).append('\'');
        sb.append('}');
        return sb.toString();
    }
}

/**
 * 负责类.作用仅仅是存储备忘录对象,而不允许改变备忘录对象。
 * Created by z3jjlzt on 2018/2/5.
 */
public class MementoCaretaker {
    private Stack<Memento> undolst = new Stack<>();
    private Stack<Memento> redolst = new Stack<>();

    /**
     * 进行新的操作.
     */
    public void operator(Memento memento) {
        redolst.clear();//先清空redo栈.
        undolst.push(memento);
    }

    public Memento undo(Formula formula) {
        redolst.push(formula.createMemento());
        return undolst.pop();
    }

    public Memento redo(Formula formula) {
        undolst.push(formula.createMemento());
        return redolst.pop();
    }
}

/**
 * Created by z3jjlzt on 2018/2/5.
 */
public class Client {
    public static void main(String[] args) {
        Formula formula = new Formula();
        formula.setState("1*3");
        MementoCaretaker caretaker = new MementoCaretaker();
        Memento op = formula.op("-4");
        caretaker.operator(op);
        Memento op1 = formula.op("*5");
        caretaker.operator(op1);
        Memento op2 = formula.op("/6");
        caretaker.operator(op2);
        System.out.println(formula);
        formula.restoreFromMemento(caretaker.undo(formula));
        System.out.println(formula);
        formula.restoreFromMemento(caretaker.redo(formula));
        System.out.println(formula);
        formula.restoreFromMemento(caretaker.undo(formula));
        System.out.println(formula);
        formula.restoreFromMemento(caretaker.undo(formula));
        System.out.println(formula);
        formula.restoreFromMemento(caretaker.undo(formula));
        System.out.println(formula);
        formula.restoreFromMemento(caretaker.redo(formula));
        System.out.println(formula);
        formula.restoreFromMemento(caretaker.redo(formula));
        System.out.println(formula);
        formula.restoreFromMemento(caretaker.redo(formula));
        System.out.println(formula);
    }
}
运行结果:
Formula{state='1*3-4*5/6'}
Formula{state='1*3-4*5'}
Formula{state='1*3-4*5/6'}
Formula{state='1*3-4*5'}
Formula{state='1*3-4'}
Formula{state='1*3'}
Formula{state='1*3-4'}
Formula{state='1*3-4*5'}
Formula{state='1*3-4*5/6'}

0xff 总结

  • 优点:提供了一种状态恢复的机制。
  • 缺点:在原发器的state数目过多时,资源消耗过大。
  • 适用场景:系统需要提供状态恢复的机制。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值