趣解设计模式之《珍爱生命,远离<只狼>》

〇、小故事

小王最近打算入手一款叫《只狼》的游戏,这款游戏特别的硬核,也就是说,普通的小怪战斗力都特别的强,而作为主角的我们,也很容易被小兵打败

除了游戏中的小兵和Boss很难打败之外,如果在游戏中被杀了,也需要从这章的开头开始打,没办法直接从死亡点附近复活,这个就又为游戏增加了难度。不过,对这款游戏痴迷的玩家依然很多很多。但是,我们假设一种情况,就是,**如果在游戏中失败了,直接从游戏第一关开始,你还会玩吗?**估计这种情况下,大多数玩家都会被劝退了。

今天我们讨论的并不是《只狼》这款游戏如何通关的问题,而是游戏中必不可少的两个通用的功能:存档读档 。正是这两个功能,使得我们更容易将游戏通关,而不是每次失败后都要从第一章的第一关重新开始玩。那么,我们现在就开始讲解今天要介绍的设计模式------备忘录模式

一、模式定义

备忘录模式Memento Pattern

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以将该对象恢复到原先保存的状态。当你需要让对象返回之前的状态 时(例如:你的用户请求"撤销"),就使用备忘录模式。

二、模式类图

为了便于大家理解,再举一个日常大家几乎都会做的事情,就是当我们编辑文档或者写文章的时候,经常会回到写错了需要按ctrl+z撤销的操作(以前保存是都需要手动ctrl+s保存的,现在大多的文章编译软件都会自动帮我们保存了),那么如果有这种需求,我们可以采用备忘录模式来解决。

创建Document 类作为我们日常编辑的文档,因为要保存文档快照,所以创建Memento 类作为备忘录类,通过备忘录管理类MementoManager来实现备忘录的保存和读取,内部通过堆栈数据类型Stack保存备忘录列表。具体类图,如下所述:

三、代码实现

创建文档类Document.java

java 复制代码
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Document {
    public String content; // 文档内容
}

创建备忘录类Memento.java

java 复制代码
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Memento {
    public String content; // 文档内容
}

创建备忘录管理类MementoManager.java

java 复制代码
public class MementoManager {
    // 记录备忘录信息
    private Stack<Memento> mementoStack = new Stack<>();

    // 保存备忘录操作
    public void save(Document document) {
        Memento memento = new Memento(document.getContent());
        mementoStack.add(memento);
    }

    // 撤销操作
    public Document cancel() {
        Memento memento = mementoStack.pop();
        Document document = new Document();
        document.setContent(memento.getContent());
        return document;
    }
}

创建备忘录测试类MementoTest.java

java 复制代码
public class MementoTest {
    public static void main(String[] args) {
        MementoManager mementoManager = new MementoManager();
        System.out.println("-----执行文档修改操作-----");
        Document document = new Document();
        document.setContent("a");
        document.print();
        mementoManager.save(document);

        document.setContent("b");
        document.print();
        mementoManager.save(document);

        document.setContent("c"); // 修改后,发现写错了,想要回撤到上一个保存点
        document.print();

        System.out.println("-----执行第一次撤销操作-----");
        document = mementoManager.cancel();
        document.print();

        System.out.println("-----执行第二次撤销操作-----");
        document = mementoManager.cancel();
        document.print();
    }
}

运行结果如下所示

java 复制代码
-----执行文档修改操作-----
content=a
content=b
content=c
-----执行第一次撤销操作-----
content=b
-----执行第二次撤销操作-----
content=a

Process finished with exit code 0

今天的文章内容就这些了:

写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享

更多技术干货,欢迎大家关注公众号"爪哇缪斯" ~ \(^o^)/ ~ 「干货分享,每天更新」

相关推荐
想打游戏的程序猿4 小时前
核心概念层——深入理解 Agent 是什么
后端·ai编程
woniu_maggie5 小时前
SAP Web Service日志监控:如何用SRT_UTIL快速定位接口问题
后端
一线大码5 小时前
Java 使用国密算法实现数据加密传输
java·spring boot·后端
Rust语言中文社区5 小时前
【Rust日报】用 Rust 重写的 Turso 是一个更好的 SQLite 吗?
开发语言·数据库·后端·rust·sqlite
在屏幕前出油6 小时前
06. FastAPI——中间件
后端·python·中间件·pycharm·fastapi
wuqingshun3141597 小时前
说一下spring的bean的作用域
java·后端·spring
钟智强7 小时前
从2.7GB到481MB:我的Docker Compose优化实战,以及为什么不能全信AI
后端·docker
华科易迅8 小时前
Spring JDBC
java·后端·spring
小村儿8 小时前
一起吃透 Claude Code,告别 AI 编程迷茫
前端·后端·ai编程
程序员大飞哥8 小时前
云控SLA的数学:250ms端到端延迟预算怎么分配给传输层
后端