25 行为型模式-备忘录模式

news2024/11/17 19:44:57
1 备忘录模式介绍在这里插入图片描述

备忘录模式(memento pattern)定义: 在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态.

2 备忘录模式原理

在这里插入图片描述
在这里插入图片描述

3 备忘录模式实现

在这里插入图片描述

/**
 * 发起人角色
 **/
public class Originator {

    private String state = "原始对象";

    private String id;

    private String name;

    private String phone;

    public Originator() {
    }

    //创建备忘录对象
    public Memento createMemento(){
        return new Memento(id,name,phone);
    }

    //恢复对象
    public void restoreMemento(Memento m){

        this.state = m.getState();
        this.id = m.getId();
        this.name = m.getName();
        this.phone = m.getPhone();
    }

    @Override
    public String toString() {
        return "Originator{" +
                "state='" + state + '\'' +
                ", id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", phone='" + phone + '\'' +
                '}';
    }

    public String getState() {
        return state;
    }

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

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }
}
/**
 * 备忘录角色
 * 访问权限为: 默认,在同包下可见(尽量保证只有发起者类可以访问备忘录类)
 **/
class Memento {

    private String state = "从备份对象恢复原始对象";

    private String id;

    private String name;

    private String phone;

    public Memento() {
    }

    public Memento(String id, String name, String phone) {
        this.id = id;
        this.name = name;
        this.phone = phone;
    }

    public String getState() {
        return state;
    }

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

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    @Override
    public String toString() {
        return "Memento{" +
                "state='" + state + '\'' +
                ", id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", phone='" + phone + '\'' +
                '}';
    }
}
/**
 * 负责人类-获取和保存备忘录对象
 **/
public class Caretaker {

    private Memento memento;

    public Memento getMemento() {
        return memento;
    }

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

    public static void main(String[] args) {

        //创建发起人对象
        Originator o1 = new Originator();
        o1.setId("1");
        o1.setName("spike");
        o1.setPhone("13522777722");
        System.out.println("========"+o1);

        //创建负责人对象
        Caretaker caretaker = new Caretaker();
        caretaker.setMemento(o1.createMemento());

        //修改
        o1.setName("update");
        System.out.println("========" + o1);

        //从负责人对象中获取备忘录对象,实现恢复操作
        o1.restoreMemento(caretaker.getMemento());
        System.out.println("========" + o1);
    }
}
4 备忘录模式应用实例

在这里插入图片描述

/**
 * 备份玩家的状态
 **/
class Memento {

    private int money;  //玩家获取的金币

    ArrayList fruits;  //玩家获取的水果

    public Memento(int money) {
        this.money = money;
        this.fruits = new ArrayList();
    }

    //获取当前玩家的金币
    public int getMoney(){
        return money;
    }

    //获取当前玩家的水果
    List getFruits(){
        return (List) fruits.clone();
    }

    //添加水果
    void addFruit(String fruit){
        fruits.add(fruit);
    }

}

Player玩家类,只要玩家的金币还够,就会一直进行游戏,在该类中会设置一个createMemento方法,其作用是保存当前玩家状态.还会包含一个restore撤销方法,相当于复活操作.

/**
 * 玩家类
 **/
public class Player {

    private int money;  //金币

    private List<String> fruits = new ArrayList<>();  //玩家获得的水果

    private static String[] fruitsName ={   //表示水果种类的数组
            "苹果","葡萄","香蕉","橘子"
    };

    Random random = new Random();

    public Player(int money) {
        this.money = money;
    }

    //获取当前所有金币
    public int getMoney(){
        return money;
    }

    //获取一个水果
    public String getFruit(){
        String prefix = "";
        if(random.nextBoolean()){
            prefix = "好吃的";
        }

        //从数组中拿一个水果
        String f = fruitsName[random.nextInt(fruitsName.length)];
        return prefix + f;
    }

    //掷骰子方法
    public void yacht(){

        int dice = random.nextInt(6) + 1; //掷骰子

        if(dice == 1){
            money += 100;
            System.out.println("所持有的金币增加了...");
        }else if(dice == 2){
            money /= 2;
            System.out.println("所持有的金币减少一半");
        }else if(dice == 6){ //获取水果
            String fruit = getFruit();
            System.out.println("获取了水果: " + fruit);
            fruits.add(fruit);
        }else{
            //其他结果
            System.out.println("无效数字,继续投掷!");
        }
    }

    //拍摄快照
    public Memento createMemento(){
        Memento memento = new Memento(money);
        for (String fruit : fruits) {

            //判断: 只保存 '好吃的'水果
            if(fruit.startsWith("好吃的")){
                memento.addFruit(fruit);
            }
        }

        return memento;
    }


    //撤销方法
    public void restoreMemento(Memento memento){
        this.money = memento.getMoney();
        this.fruits = memento.getFruits();
    }


    @Override
    public String toString() {
        return "Player{" +
                "money=" + money +
                ", fruits=" + fruits +
                '}';
    }
}

测试: 由于引入了备忘录模式,可以保存某个时间点的玩家状态,这样就可以对玩家进行复活操作.

public class MainApp {

    public static void main(String[] args) throws InterruptedException {

        //创建玩家类,设置初始金币
        Player player = new Player(100);

        //创建备忘录对象
        Memento memento = player.createMemento();

        for (int i = 0; i < 100; i++) {

            //显示扔骰子的次数
            System.out.println("第" + i+"次投掷!");

            //显示当前玩家状态
            System.out.println("当前状态: " + player);

            //开启游戏
            player.yacht();
            System.out.println("玩家所持有的金币: " + player.getMoney() + " 元");

            //复活操作
            if(player.getMoney() > memento.getMoney()){
                System.out.println("赚到金币,保存当前状态,继续游戏!");
                memento = player.createMemento();  //更新快照
            }else if(player.getMoney() < memento.getMoney() / 2){
                System.out.println("所持金币不多,将游戏恢复到初始状态!");
                player.restoreMemento(memento);
            }

            Thread.sleep(1000);
        }
    }
}
5 备忘录模式总结

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1142416.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

城中村智能电表改造解决方案

随着我国城市化进程的加快&#xff0c;城中村作为城市发展的矛盾焦点&#xff0c;其居住环境、管理水平等问题日益凸显。城中村用电管理存在着用电安全隐患、电费核算不准确、偷电现象屡禁不止等问题。为了提高城中村用电管理水平&#xff0c;确保用电安全&#xff0c;推进智能…

通过pip,查看tensorflow和tensorflow-probaility版本

查看tensorflow和tensorflow-probability版本 如果在加载tensorflow 和 tensorflow-probablity时&#xff0c;没有成功的话&#xff0c;可以看下这两个包的版本&#xff0c;网上可以搜一下&#xff0c;这两个包版本是否搭配。 从上述信息总可以看到tensorflow包的版本是2.13.0…

DSP开发例程(4): logbuf_print_to_uart

目录 DSP开发例程: logbuf_print_to_uart新建工程源码编辑app.cfgos.cmain.c 调试说明 DSP开发例程: logbuf_print_to_uart SYS/BIOS 提供了 xdc.runtime.Log, xdc.runtime.LoggerBuf 和 xdc.runtime.LoggerSys 这几个模块用于日志记录. 日志信息在 应用程序调试和状态监控中非…

Web服务器与Http协议

Web服务器与Http协议 一.Web服务器 1.简介 Web服务器一般指网站服务器&#xff0c;也称之为WWW(World Wide Web)服务器Web服务器是指驻留于因特网上某种类型计算机的程序Web服务器不是硬件服务器&#xff0c;而是软件服务器。Web服务器其主要功能是提供网上信息浏览服务&…

论文阅读——BERT

ArXiv&#xff1a;https://arxiv.org/abs/1810.04805 github&#xff1a;GitHub - google-research/bert: TensorFlow code and pre-trained models for BERT 一、模型及特点&#xff1a; 1、模型&#xff1a; 深层双向transformer encoder结构 BERT-BASE&#xff1a;(L12, H…

2.19每日一题(分段函数求定积分)

注意&#xff1a;当x>1时需要分区间求定积分 用变上限积分的定理&#xff1a;如果 f(x) 连续&#xff0c;则 F(x) 的导数 f(x) 变上限积分的导数为 f(x) 1、先判断 f(x) 是否连续———>判断在分界点的值是否相等&#xff0c;相等则 f(x) 连续&#xff0c;则 F(x&#…

实体店做商城小程序如何

互联网电商深入各个行业&#xff0c;传统线下店商家无论产品销售还是服务业&#xff0c;仅靠以往的经营模式&#xff0c;很难拓展到客户&#xff0c;老客流失严重&#xff0c;同时渠道单一&#xff0c;无法实现外地客户购物及线上客户赋能等。 入驻第三方平台有优势但也有不足…

Java练习题2020-4

小明今天收了N个鸡蛋&#xff0c;每个鸡蛋各有重量&#xff0c;现在小明想找M个重量差距最小的鸡蛋摆成一盒出售&#xff0c;输出符合条件的最重一盒鸡蛋的总重量 输入说明&#xff1a;第一行&#xff0c;鸡蛋个数N(N<1000) 每盒个数M(M<N)&#xff1b;第二行&#xff0…

如何使用PHPicker在iOS系统无授权下获取资源

本文字数&#xff1a;2766字 预计阅读时间&#xff1a;18分钟 自iOS14系统开始&#xff0c;苹果加强了用户隐私和安全功能。新增了“Limited Photo Library Access”模式&#xff0c;同时在授权弹窗中增加了“Select Photo”选项。这意味着用户可以在应用程序请求访问相册时选择…

Unity编辑器扩展之自定义Inspector面板

首先找到的是这个[CustomEditor(typeof(Class), true)]&#xff0c;这个东西能够自己绘制在Inspector视图的显示规则&#xff0c;但是&#xff01;如果这个类被另一个类持有&#xff0c;他就没作用了&#xff0c; 效果图&#xff1a; 1.对CustomClass类编辑自定义面板 2. 对M…

为什么Facebook运营需使用IP代理?

随着互联网的快速发展和全球用户规模的不断增长&#xff0c;Facebook已成为了全球最大的社交媒体平台之一。然而&#xff0c;大批量地运营Facebook账号往往需要借助IP代理这一工具&#xff0c;提高账号的安全性和可靠性&#xff0c;使得运营Facebook更加流畅。那么Facebook为什…

QGIS008:QGIS拓扑检查、修改及验证

摘要&#xff1a;本文介绍使用QGIS拓扑检查器和几何图形检查器检查图层的拓扑错误&#xff0c;修改拓扑错误&#xff0c;并对修改后的图层进行错误验证。 实验数据&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1Vy2s-KYS-XJevqHNdavv9A?pwdf06o 提取码&#xff1a…

源码角度分析Java 循环中删除数据为什么会报异常

一、源码角度分析Java 循环中删除数据为什么会报异常 相信大家在之前或多或少都知道 Java 中在增强 for中删除数据会抛出&#xff1a;java.util.ConcurrentModificationException 异常&#xff0c;例如&#xff1a;如下所示程序&#xff1a; public class RmTest {public sta…

系统架构师-第10章-软件架构的演化和维护-学习笔记

软件架构一般会经历初始设计、实际使用、修改完善和退化弃阳的过程&#xff0c;其中修改完善的过程实际上就是软件架构的演化和维护过程&#xff0c;演化和维护的H 的就是为f 侦软件能够适应环境的变化而进行的纠铺性修改和完善性修改等。 软件架构演化和定义的关系 演化的重…

069:mapboxGL加载GPX,转换为geojson,显示图形

第069个 点击查看专栏目录 本示例是演示如何在vue+mapbox中加载GPX,转换为geojson,在地图上显示图形。这里面用到了大剑师的gpx2geojson插件,很方便的做了数据的转换。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果所用的gpx文件配置方…

【开源】基于SpringBoot的衣物搭配系统的设计和实现

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 衣物档案模块2.2 衣物搭配模块2.3 衣物收藏模块 三、系统设计3.1 用例设计3.2 E-R图设计3.3 数据库设计3.3.1 衣物档案表3.3.2 衣物搭配表3.3.3 衣物收藏表 四、系统实现4.1 登录页4.2 衣物档案模块4.3 衣物搭配模块4.4…

力扣每日一题79:单词搜索

题目描述&#xff1a; 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格…

25-什么是事件循环

一、是什么 &#x1f37f;&#x1f37f;&#x1f37f;JavaScript是一门单线程的语言、 意味着同一时间内只能做一件事&#xff0c;但是这并不意味着单线程就是阻塞&#xff0c;而实现单线程非阻塞的方法就是事件循环 在JavaScript中&#xff0c;所有的任务都可以分为 同步任…

C++学习 day--20 new和delete关键字

1、new 和 delete 基本语法 1 &#xff09;在软件项目开发过程中&#xff0c;我们经常需要动态地分配和撤销内存空间&#xff0c;特别是数据结构中结点的插入与删除。在 C 语言中是利用库函数 malloc 和 free 来分配和撤销内存空间的。C 提供了较简便而功能较强的运算符 …

Screenium for Mac: 重新定义屏幕录制体验

你是否曾经需要记录你的屏幕活动&#xff0c;但却被复杂的软件界面和功能缺失所困扰&#xff1f;现在&#xff0c;Screenium for Mac可以解决你的烦恼。这是一款全新的屏幕录制工具&#xff0c;以其强大的功能和易用性&#xff0c;让你的屏幕录制体验焕然一新。 Screenium for…