【Java 行为型设计模式 VI】备忘录模式详解

 
愿你如阳光,明媚不忧伤。

 


12. 备忘录模式

Memento 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。该模式又叫快照模式。如 Word、记事本、Photoshop、Eclipse 等软件在编辑时按 Ctrl+Z 组合键时能撤销当前操作,使文档恢复到之前的状态。

备忘录模式优点和缺点
  • 优点
  1. 提供了一种可以恢复状态的机制。当用户需要时能够比较方便地将数据恢复到某个历史的状态。
  2. 实现了内部状态的封装。除了创建它的发起人之外,其他对象都不能够访问这些状态信息。
  3. 简化了发起人类。发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则。
  • 缺点
  1. 资源消耗大。如果要保存的内部状态信息过多或者特别频繁,将会占用比较大的内存资源。
备忘录模式的应用场景
  1. 需要保存与恢复数据的场景,如玩游戏时的中间结果的存档功能。
  2. 需要提供一个可回滚操作的场景,如 Word、记事本、Photoshop,Eclipse 等软件在编辑时按 Ctrl+Z 组合键,还有数据库中事务操作。
备忘录模式模式的结构
备忘录模式的核心是设计备忘录类以及用于管理备忘录的管理者类。
1. 发起人(Originator)角色:记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。
2. 备忘录(Memento)角色:负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。
3. 管理者(Caretaker)角色:对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。
发起人Originator +setState(String state) : void +getState() : String +createMemento() : Memento +restoreMemento(Memento memento) : void 备忘录Memento -state:String +Memento(String state) +setState(String state) : void +getState() : String 管理者Caretaker -memento:Memento +setMemento(Memento memento) : void +getMemento() : Memento 访问类Client +main() : void Aggregate
备忘录模式的实现
package com.example.demo.controller;

public class MementoController {
    public static void main(String[] args) {
        Originator originator = new Originator();
        Caretaker caretaker = new Caretaker();
        originator.setState("S0");
        System.out.println("初始状态:" + originator.getState());
        // 保存状态
        caretaker.setMemento(originator.createMemento());
        // 设置新的状态
        originator.setState("S1");
        System.out.println("新的状态:" + originator.getState());
        // 恢复状态
        originator.restoreMemento(caretaker.getMemento());
        System.out.println("恢复状态:" + originator.getState());
    }
}

// 备忘录
class Memento {
    private String state;

    public Memento(String state) {
        this.state = state;
    }

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

    public String getState() {
        return state;
    }
}

// 发起人
class Originator {
    private String state;

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

    public String getState() {
        return state;
    }

    public Memento createMemento() {
        return new Memento(state);
    }

    public void restoreMemento(Memento memento) {
        this.setState(memento.getState());
    }
}

// 管理者
class Caretaker {
    private Memento memento;

    public void setMemento(Memento memento) {
        this.memento = memento;
    }

    public Memento getMemento() {
        return memento;
    }
}
-----------------------------------------------------------------
・【运行结果】
	初始状态:S0
	新的状态:S1
	恢复状态:S0

备忘录模式的扩展

clone() 方法具有自备份功能,所以,如果让发起人实现 Cloneable 接口就有备份自己的功能,这时可以删除备忘录类。

  • 原型备忘录模式
发起人原型OriginatorPrototype -state:String +setState(String state) : void +getState() : String +createMemento() : OriginatorPrototype +restoreMemento(OriginatorPrototype opt) : void +clone() : OriginatorPrototype «Interface» 克隆接口Cloneable +clone() : Object 管理者原型CaretakerPrototype -opt:OriginatorPrototype +setMemento(OriginatorPrototype opt) : void +getMemento() : OriginatorPrototype 访问类Client +main() : void Relazition Aggregate
package com.example.demo.controller;

public class MementoController {
    public static void main(String[] args) throws CloneNotSupportedException {
        OriginatorPrototype opt = new OriginatorPrototype();
        CaretakerPrototype caretaker = new CaretakerPrototype();
        opt.setState("S0");
        System.out.println("初始状态:" + opt.getState());
        // 保存状态
        caretaker.setMemento(opt.createMemento());
        // 设置新的状态
        opt.setState("S1");
        System.out.println("新的状态:" + opt.getState());
        // 恢复状态
        opt.restoreMemento(caretaker.getMemento());
        System.out.println("恢复状态:" + opt.getState());
    }
}

/*// 备忘录
class Memento {
    private String state;

    public Memento(String state) {
        this.state = state;
    }

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

    public String getState() {
        return state;
    }
}*/

// 发起人
class OriginatorPrototype implements Cloneable{
    private String state;

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

    public String getState() {
        return state;
    }

/*    public Memento createMemento() {
        return new Memento(state);
    }

    public void restoreMemento(Memento memento) {
        this.setState(memento.getState());
    } */

    public OriginatorPrototype createMemento() throws CloneNotSupportedException {
        return (OriginatorPrototype) this.clone();
    }

    public void restoreMemento(OriginatorPrototype opt) {
        this.setState(opt.getState());
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

// 管理者
class CaretakerPrototype {
    private OriginatorPrototype opt;

    public void setMemento(OriginatorPrototype opt) {
        this.opt = opt;
    }

    public OriginatorPrototype getMemento() {
        return opt;
    }
}
-----------------------------------------------------------------
・【运行结果】
	初始状态:S0
	新的状态:S1
	恢复状态:S0

 


【每日一面】

一句话归纳设计模式
分类设计模式简述一句话归纳目的生活案例
创建型1工厂模式不同条件下创建不同实例产品标准化,生产更高效封装创建细节实体工厂
创建型2单例模式保证一个类仅有一个实例,并且提供一个全局访问点世上只有一个我保证独一无二CEO
创建型3原型模式通过拷贝原型创建新的对象拔一根猴毛,吹出千万个高效创建对象克隆
创建型4建造者模式用来创建复杂的复合对象高配中配和低配,想选哪配就哪配开放个性配置步骤选配
结构型1代理模式为其他对象提供一种代理以控制对这个对象的访问没有资源没时间,得找别人来帮忙增强职责,附加功能媒婆
结构型2外观模式对外提供一个统一的接口用来访问子系统打开一扇门,通向全世界统一访问入口前台
结构型3装饰器模式为对象添加新功能他大舅他二舅都是他舅灵活扩展、同宗同源煎饼
结构型4享元模式使用对象池来减少重复对象的创建优化资源配置,减少重复浪费共享资源池全国社保联网
结构型5组合模式将整体与局部(树形结构)进行递归组合,让客户端能够以一种的方式对其进行处理人在一起叫团伙,心在一起叫团队统一整体和个体组织架构树
结构型6适配器模式将原来不兼容的两个类融合在一起万能充电器兼容转换电源适配
结构型7桥接模式将两个能够独立变化的部分分离开来约定优于配置不允许用继承
行为型1模板模式定义一套流程模板,根据需要实现模板中的操作流程全部标准化,需要微调请覆盖逻辑复用把大象装进冰箱
行为型2策略模式封装不同的算法,算法之间能互相替换条条大道通罗马,具体哪条你来定把选择权交给用户选择支付方式
行为型3责任链模式拦截的类都实现统一接口,每个接收者都包含对下一个接收者的引用。将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止各人自扫门前雪,莫管他们瓦上霜解耦处理逻辑踢皮球
行为型4迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素流水线上坐一天,每个包裹扫一遍统一对集合的访问方式逐个检票进站
行为型5命令模式将请求封装成命令,并记录下来,能够撤销与重做运筹帷幄之中,决胜千里之外解耦请求和处理遥控器
行为型6状态模式根据不同的状态做出不同的行为状态驱动行为,行为决定状态绑定状态和行为订单状态跟踪
行为型7备忘录模式保存对象的状态,在需要时进行恢复失足不成千古恨,想重来时就重来备份、后悔机制草稿箱
行为型8中介者模式将对象之间的通信关联关系封装到一个中介类中单独处理,从而使其耦合松散联系方式我给你,怎么搞定我不管统一管理网状资源朋友圈
行为型9解释器模式给定一个语言,定义它的语法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子我想说”方言“,一切解释权都归我实现特定语法解析摩斯密码
行为型10观察者模式状态发生改变时通知观察者,一对多的关系到点就通知我解耦观察者与被观察者闹钟
行为型11访问者模式稳定数据结构,定义新的操作行为横看成岭侧成峰,远近高低各不同解耦数据结构和数据操作KPI考核
行为型12委派模式允许对象组合实现与继承相同的代码重用,负责任务的调用和分配这个需求很简单,怎么实现我不管只对结果负责授权委托书
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值