ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

备忘录模式

2021-04-03 10:32:19  阅读:208  来源: 互联网

标签:状态 scene 模式 SceneMemento lifeValue 备忘录 public


备忘录模式

一、备忘录模式

备忘录模式(Memento Pattern)是一种对象行为型模式,又叫快照模式,别名为Token。

定义在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。
使用频率:2星
模式结构
备忘录模式的主要角色如下:
1、发起人(Originator)角色:记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。
2、备忘录(Memento)角色:负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。
3、管理者(Caretaker)角色:对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。
备忘录模式结构图
在这里插入图片描述
优点
1、提供了一种可以恢复状态的机制。当用户需要时能够比较方便地将数据恢复到某个历史的状态。
2、实现了内部状态的封装。除了创建它的发起人之外,其他对象都不能够访问这些状态信息。
3、简化了发起人类。发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则。
缺点
资源消耗大。如果要保存的内部状态信息过多或者特别频繁,将会占用比较大的内存资源。
应用场景
1、需要保存与恢复数据的场景,如玩游戏时的中间结果的存档功能。
2、需要提供一个可回滚操作的场景,如 Word、记事本、Photoshop,Eclipse 等软件在编辑时按 Ctrl+Z 组合键,还有数据库中事务操作。

二、备忘录模式实例之游戏恢复点设置

1.实例说明

某游戏为了给玩家提供更好的用户体验,在游戏过程中设置一个恢复点,记录当前游戏场景,如果在后续游戏中玩家角色“不幸牺牲”,可以返回到先前场景。使用备忘录模式设计该功能。

2.实例类图

在这里插入图片描述

3.实例代码

本例中,GameScene充当原发器角色,它是待保存历史状态的类;SceneMemento充当备忘录角色,它存储了GameScene的历史状态;Caretaker充当负责人角色,它用于管理备忘录。

//游戏场景类:原发器
class GameScene{
    private String scene;
    private int lifeValue;

    public void restore(SceneMemento m){
        this.scene=m.getScene();
        this.lifeValue=m.getLifeValue();
    }
    public SceneMemento save(){
        return new SceneMemento(this.scene,this.lifeValue);
    }
    public void display(){
        System.out.println("当前游戏场景为:"+this.scene+",");
        System.out.println("您还有"+this.lifeValue+"条命");
    }

    // Getter & Setter
    public String getScene() {
        return scene;
    }

    public void setScene(String scene) {
        this.scene = scene;
    }

    public int getLifeValue() {
        return lifeValue;
    }

    public void setLifeValue(int lifeValue) {
        this.lifeValue = lifeValue;
    }
}

//场景备忘录:备忘录
class SceneMemento{
    private String scene;
    private int lifeValue;

    public SceneMemento(String scene, int lifeValue) {
        this.scene = scene;
        this.lifeValue = lifeValue;
    }

    // Getter & Setter
    public String getScene() {
        return scene;
    }

    public void setScene(String scene) {
        this.scene = scene;
    }

    public int getLifeValue() {
        return lifeValue;
    }

    public void setLifeValue(int lifeValue) {
        this.lifeValue = lifeValue;
    }
}

//负责人
class Caretaker{
    private SceneMemento memento;

    // Getter & Setter
    public SceneMemento getMemento() {
        return memento;
    }

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

客户端测试:

public class Client {
    public static void main(String[] args) {
        GameScene scene = new GameScene();
        Caretaker ct = new Caretaker();
        scene.setScene("无名湖");
        scene.setLifeValue(3);
        System.out.println("原始状态");
        scene.display();
        ct.setMemento(scene.save());//原始状态存档
        System.out.println("------------------");

        scene.setScene("魔鬼洞");
        scene.setLifeValue(0);
        System.out.println("牺牲状态");
        scene.display();
        System.out.println("------------------");

        scene.restore(ct.getMemento());//加载原始状态存档
        System.out.println("恢复到原始状态");
        scene.display();
        System.out.println("------------------");
    }
}

运行结果:

原始状态
当前游戏场景为:无名湖,
您还有3条命
------------------
牺牲状态
当前游戏场景为:魔鬼洞,
您还有0条命
------------------
恢复到原始状态
当前游戏场景为:无名湖,
您还有3条命
------------------

原发器GameScene调用save方法后将产生一个备忘录对象,该备忘录对象将保存在Caretaker中,原发器需要恢复状态时再将其从Caretaker中取出,可以通过调用restore方法来获取存储在备忘录中的状态信息。真实开发中,除了原发器可以创建备忘录并赋值外,其他对象不应该直接调用备忘录中的方法,也不能创建备忘录。如果备忘录被原发器以外的第三者改动,则原发器恢复到历史状态不是真实的历史状态,而是修改过的,这违背了备忘录模式的设计初衷,因此需要对备忘录进行封装。

参考文献

【1】备忘录模式(详解版)
【2】设计模式实训教程(第2版) 刘伟 编著 清华大学出版社

标签:状态,scene,模式,SceneMemento,lifeValue,备忘录,public
来源: https://blog.csdn.net/weixin_43594279/article/details/115412811

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有