设置模式——备忘录模式

news2024/12/23 9:55:26

备忘录模式

备忘录模式(Memento Design Pattern),也叫快照(Snapshot)模式。指在不违背封装原则前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便之后恢复对象为先前的状态。

备忘录模式主要包含以下几个角色:

Originator(发起人):负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复状态。Originator可根据需求决定Memento存储Originator的哪些内部状态。

Memento(备忘录):负责存储Originator对象的内部状态,并可防止Originator以外的其他对象访问备忘录Memento。备忘录有两个接口,Caretaker只能看到备忘录的窄接口,它只能将备忘录传递给其他对象。Originator能够看到一个宽接口,允许它访问返回到先前状态所需的所有数据。

Caretaker(管理者):负责保存好备忘录Memento,不能对备忘录的内容进行操作或检查。

 备忘录模式的实现

在利用备忘录模式时,首先应该设计一个组织者类(Originator),它是一个具体的业务类,存储当前状态。它包含备忘录对象的创建方法createMemeto()和备忘录对象恢复方restoreMemeto()

发起人(Originator)类

public class Originator {

    //需要保存的属性
    private String state;

    //创建备忘录,将当前需要保存的信息导入并实例化出一个Memento对象
    public Memento createMemento() {
        return new Memento(state);
    }

    //恢复备忘录,将Memento导入并将相关数据恢复
    public void setMemento(Memento memento) {
        this.state = memento.getState();
    }

    //显示数据
    public void show() {
        System.out.println("state = " + state);
    }

    public String getState() {
        return state;
    }

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

管理者(Caretaker)类

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 originator = new Originator();
        originator.setState("1");
        originator.show();

        Caretaker caretaker = new Caretaker();
        caretaker.setMemento(originator.createMemento());

        originator.setState("0");
        originator.show();

        originator.setMemento(caretaker.getMemento());
        originator.show();

    }

}

 运行结果

state = 1
state = 0
state = 1

模式实现 

在学习的过程发现一个很好的应用实例场景:

文章作者: leisurexi
新博客地址: https://leisurexi.github.io

实例是这样的:

实现场景:

游戏中的某个场景,一游戏角色有生命力、攻击力、防御力等数据,在打Boss前和后一定会不一样的,我们允许玩家如果感觉与Boss决斗的效果不理想可以让游戏恢复到决斗之前。

代码结构图 :

游戏角色类
public class GameRole {

    private int vit; //生命力
    private int atk; //攻击力
    private int def; //防御力

    //初始化状态
    public void initState() {
        this.vit = 100;
        this.atk = 100;
        this.def = 100;
    }

    //战斗
    public void fight() {
        this.vit = 0;
        this.atk = 0;
        this.def = 0;
    }

    //保存角色状态
    public RoleStateMemento saveState() {
        return new RoleStateMemento(vit, atk, def);
    }

    //回复角色状态
    public void recoverState(RoleStateMemento roleStateMemento) {
        this.vit = roleStateMemento.getVit();
        this.atk = roleStateMemento.getAtk();
        this.def = roleStateMemento.getDef();
    }

    public void stateDisplay() {
        System.out.println("角色生命力:" + vit);
        System.out.println("角色攻击力:" + atk);
        System.out.println("角色防御力:" + def);

    }

    public int getVit() {
        return vit;
    }

    public void setVit(int vit) {
        this.vit = vit;
    }

    public int getAtk() {
        return atk;
    }

    public void setAtk(int atk) {
        this.atk = atk;
    }

    public int getDef() {
        return def;
    }

    public void setDef(int def) {
        this.def = def;
    }
}
游戏状态存储类 
public class RoleStateMemento {

    private int vit;
    private int atk;
    private int def;

    public RoleStateMemento(int vit, int atk, int def) {
        this.vit = vit;
        this.atk = atk;
        this.def = def;
    }

    public int getVit() {
        return vit;
    }

    public void setVit(int vit) {
        this.vit = vit;
    }

    public int getAtk() {
        return atk;
    }

    public void setAtk(int atk) {
        this.atk = atk;
    }

    public int getDef() {
        return def;
    }

    public void setDef(int def) {
        this.def = def;
    }
}
角色状态管理者类 
public class RoleStateCaretaker {

    private RoleStateMemento roleStateMemento;

    public RoleStateMemento getRoleStateMemento() {
        return roleStateMemento;
    }

    public void setRoleStateMemento(RoleStateMemento roleStateMemento) {
        this.roleStateMemento = roleStateMemento;
    }
}
客户端程序 
public class Client {

    public static void main(String[] args) {

        System.out.println("------------大战Boss前------------");
        //大战Boss前
        GameRole gameRole = new GameRole();
        gameRole.initState();
        gameRole.stateDisplay();

        //保存进度
        RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker();
        roleStateCaretaker.setRoleStateMemento(gameRole.saveState());
        System.out.println("------------大战Boss后------------");
        //大战Boss时,损耗严重
        gameRole.fight();
        gameRole.stateDisplay();
        System.out.println("------------恢复之前状态------------");
        //恢复之前状态
        gameRole.recoverState(roleStateCaretaker.getRoleStateMemento());
        gameRole.stateDisplay();

    }

}
运行结果 
------------大战Boss前------------
角色生命力:100
角色攻击力:100
角色防御力:100
------------大战Boss后------------
角色生命力:0
角色攻击力:0
角色防御力:0
------------恢复之前状态------------
角色生命力:100
角色攻击力:100
角色防御力:100

 

模式的优缺点

优点

  • 实现了信息的封装,使得用户不需要关心状态的保存细节。
  • 给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。

缺点

  • 如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存

 

 

 

 

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

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

相关文章

【Linux】指令

1. 简单指令 whoami 显示当前登入账号名 ls /home 现在有的用户名 adduser 用户名 新加用户(必须在root目录下) passwd 用户名 给这个用户设置密码 userdel -r 用户名 删除这个用户 pwd 显示当前所处路径 stat 文件名 / 文件夹名 显示文件状…

【Linux网络编程】网络编程套接字(TCP服务器)

【Linux网络编程】网络编程套接字(TCP服务器) 目录 【Linux网络编程】网络编程套接字(TCP服务器)地址转换函数关于inet_ntoa 简单的TCP网络程序TCP sockot API详解socket()bind()listen()accept();connect 完整的TCP服务器代码(线程池版) 作者&#xff1…

云谈网页聊天室的web自动化测试 性能测试 (包含测试代码和测试的详细过程)

概要 项目名称:云谈网页聊天室测试日期:2024-03-05测试人员:汪汪miao~测试类型:功能测试、集成测试,接口测试、性能测试测试框架&工具:Selenium、Junit、LoadRunner 项目背景 云谈网页聊天室是一款实…

【算法】两数之和(暴力求解+哈希表)

本题来源---《两数之和》。 题目描述 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里…

OPPO云VPC网络实践

1 OPPO 云网络现状 随着OPPO业务的快速发展,OPPO云规模增长迅速。大规模虚拟实例的弹性伸缩、低延时需求对网络提出了诸多挑战。原有基于VLAN搭建的私有网络无法解决这些问题,给网络运维和业务的快速上线带来了挑战。 梳理存在的主要问题如下&#xf…

redis 集群模式(redis cluster)介绍

目录 一 redis cluster 相关定义 1, redis cluster 是什么 2,redis 集群的组成 3,集群的作用 4,集群架构图 二 Redis集群的数据分片 1,哈希槽是什么 2,哈希槽如何排布 3,Redis集…

(源码+部署+讲解)基于Springboot+vue校园设施报修系统的设计与实现

前言 💗博主介绍:✌专注于Java、小程序技术领域和毕业项目实战✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 2024年Java精品实战案例《100套》 🍅文末获取源码联系🍅 &#x1f31f…

freeRTOS-day4

1.总结二进制信号量和计数型信号量的区别,以及他们的使用场景。 二进制信号量只有两个状态:0和1。它通常用于线程同步,表示某个线程执行完毕,另一个线程才能开始执行。这种特性使得二进制信号量特别适用于互斥访问共享资源的场景…

ensp 通过cloud连接交换,通过本机直连telnet交换机

#连接图 #cloud配置 绑定本机一个虚拟网卡,勾选双向通信,这样就可以通过真机直接telent到交换机 #交换机配置 #需要将管理口ip配置为绑定的虚拟网卡同网段的IP,便于直接链接 system-view sysname s5700 undo info-center en telnet server…

HTTP 常见的状态码以及其适用场景

是什么 HTTP状态码(英语:HTTP Status Code),用以表示网页服务器超文本传输协议响应状态的3位数字代码 它由 RFC 2616规范定义的,并得到 RFC 2518、RFC 2817、RFC 2295、RFC 2774与 RFC 4918等规范扩展 简单来讲&#…

什么是网络行为监控审计

网络行为监控审计,顾名思义,是指对网络使用者的行为进行实时监控,并对这些行为进行详细记录和审计的过程。 它涉及到对网络流量、用户操作、数据访问等多个方面的监控,旨在发现潜在的安全威胁和违规行为,从而保障网络…

视听杂志知网收录期刊投稿发表论文

《视听》是由国家新闻出版总署批准的正规的,兼有新闻传播、新媒体理论探索的当代学术性省级综合期刊。坚持正确的理论导向,全面展示广播影视事业发展中出现的新情况、新事物,探索现代传媒基础理论,研究网络传播、通讯传播等新媒体…

职场中持续加班的原因、影响及应对策略

在当今竞争激烈的职场环境中,加班已经成为许多行业的常态。本文将探讨持续加班的原因、对员工和企业的负面影响,以及应对持续加班的策略。 一、持续加班的原因 1. 工作任务繁重:在许多企业中,工作任务量过大,员工为了完…

Sora的阅读技术报告

sora的技术报告 走进sorasora的特性sora的介绍sora的实际操作sora的发展安全措施研究技术 走进sora 大家好,我是清风之上。随着人工智能的发展,慢慢的他已经出现在我们生活中的各个角落,其中有API推出的sora,让我们震惊不已&…

Linux多进程通信(4)——消息队列从入门到实战!

Linux多进程通信总结——进程间通信看这一篇足够啦! 1.基本介绍 1)消息队列的本质其实是一个内核提供的链表,内核基于这个链表,实现了一个数据结构,向消息队列中写数据,实际上是向这个数据结构中插入一个…

页面转word的那些事

背景 有些时候需要将页面内容或者是页面的数据通过word进行下载,以方便客户进行二次编辑,而不是直接导出图片或者是pdf。 想在页面端点击下载成word,那必然需要服务端来进行读写文件,无论是你后端编辑好的内容流,还是…

MySQL如何创建存储过程

工作中有时候需要自己去创建存储过程,然后调用存储去获得一些数据等,接下来就给大家介绍下MySQL如何创建存储过程。 语法: CREATE PROCEDURE 存储程名([[IN|OUT|INOUT] 参数名 数据类型[,[IN|OUT|INOUT] 参数名 数据类型…]]) [特性 …] 过…

git生成ssh key并推送到远端仓库

ssh-keygen -t rsa -C "anarckkgmail.com"在用户文件夹中找到id_rsa.pub,把内容复制到gitea的配置里,然后直接用git推送就可以了

HTML基础知识详解(下)(如果想知道html的全部基础知识点,那么只看这一篇就足够了!)

前言:在上一篇文章中,我们已经学习完了超链接标签、列表标签和表格标签,但是我们还有一些标签没有学习,在这篇文章中,我们将学习剩余的标签。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页…

【进阶六】Python实现SDVRPTW常见求解算法——遗传算法(GA)

基于python语言,采用经典遗传算法(GA)对 带硬时间窗的需求拆分车辆路径规划问题(SDVRP) 进行求解。 目录 往期优质资源1. 适用场景2. 代码调整2.1 需求拆分2.2 需求拆分后的服务时长取值问题 3. 求解结果4. 代码片段参…