行为型设计模式(三)状态模式 备忘录模式

news2025/1/1 20:08:12

状态模式 State

1、什么是状态模式

状态模式允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类,将对象的行为包装在不同的状态类中,对象在运行时根据内部状态的改变而改变它的行为。

2、为什么使用状态模式

  1. 封装了转换规则:状态模式将每个状态的行为封装在一个类中,使得转换规则更加清晰,易于理解和维护。
  2. 减少条件语句:状态模式减少了对象中大量的条件语句,提高了代码的可读性和可维护性。
  3. 状态切换更加灵活:状态模式使得状态切换变得更加灵活,可以在运行时动态地改变对象的状态。

3、如何使用状态模式

设计实现一个电梯状态:开门、关门、上升、下降等

// 状态接口
interface ElevatorState {
    void open();
    void close();
    void up();
    void down();
}

// 具体状态1:开门
class OpenState implements ElevatorState {
    @Override
    public void open() {
        System.out.println("The door is already open.");
    }

    @Override
    public void close() {
        System.out.println("Closing the door.");
    }

    @Override
    public void up() {
        System.out.println("Cannot go up while the door is open.");
    }

    @Override
    public void down() {
        System.out.println("Cannot go down while the door is open.");
    }
}

// 具体状态2:关门
class CloseState implements ElevatorState {
    @Override
    public void open() {
        System.out.println("Opening the door.");
    }

    @Override
    public void close() {
        System.out.println("The door is already closed.");
    }

    @Override
    public void up() {
        System.out.println("Going up.");
    }

    @Override
    public void down() {
        System.out.println("Going down.");
    }
}

// 上下文类,维护当前状态
class ElevatorContext {
    private ElevatorState currentState;

    // 设置当前状态
    void setCurrentState(ElevatorState currentState) {
        this.currentState = currentState;
    }

    // 调用状态的方法
    void open() {
        currentState.open();
    }

    void close() {
        currentState.close();
    }

    void up() {
        currentState.up();
    }

    void down() {
        currentState.down();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        ElevatorContext elevator = new ElevatorContext();

        // 初始状态为关门
        elevator.setCurrentState(new CloseState());

        // 执行操作
        elevator.open();
        elevator.up();
        elevator.close();
        elevator.down();
    }
}

4、是否存在缺陷和不足

  1. 状态模式引入了多个状态类,有可能增加系统中类的数量。
  2. 如果状态切换的逻辑比较复杂,会增加状态模式的复杂度。

5、如何缓解缺陷和不足

  1. 如果实际业务场景中,存在相似的状态行为,建议考虑合并相似行为的状态,减少状态类的数量。
  2. 尽量简化状态切换的逻辑,保持状态模式的清晰性。

备忘录模式 Memento

1、什么是备忘录模式

备忘录模式允许对象在不暴露内部状态的情况下保存和恢复状态,通过将对象的状态保存到备忘录对象中,以便后续需要时恢复到该状态。

2、为什么使用备忘录模式

  1. 封装了对象状态:备忘录模式将对象的状态封装到备忘录中,使得对象的状态对外部是不可见的。
  2. 支持撤销和恢复:备忘录模式支持将对象恢复到之前的状态,从而实现撤销的功能。

3、如何使用备忘录模式

设计实现一个文本编辑器,用户可以输入文本并且可以随时保存编辑器的状态

// 备忘录类
class EditorMemento {
    private final String content;

    EditorMemento(String content) {
        this.content = content;
    }

    String getContent() {
        return content;
    }
}

// 原发器类
class TextEditor {
    private StringBuilder content = new StringBuilder();

    // 创建备忘录
    EditorMemento createMemento() {
        return new EditorMemento(content.toString());
    }

    // 恢复备忘录
    void restoreMemento(EditorMemento memento) {
        this.content = new StringBuilder(memento.getContent());
    }

    // 修改文本内容
    void addText(String text) {
        content.append(text);
    }

    // 获取当前文本内容
    String getContent() {
        return content.toString();
    }
}

// 负责人类
class EditorHistory {
    private Stack<EditorMemento> history = new Stack<>();

    // 将备忘录保存到历史记录中
    void save(EditorMemento memento) {
        history.push(memento);
    }

    // 从历史记录中获取最近的备忘录
    EditorMemento undo() {
        if (!history.isEmpty()) {
            return history.pop();
        }
        return null;
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        TextEditor editor = new TextEditor();
        EditorHistory history = new EditorHistory();

        // 输入文本
        editor.addText("Hello, ");
        System.out.println("Current Content: " + editor.getContent());

        // 保存备忘录
        history.save(editor.createMemento());

        // 输入更多文本
        editor.addText("World!");
        System.out.println("Current Content: " + editor.getContent());

        // 撤销操作,恢复到之前的状态
        editor.restoreMemento(history.undo());
        System.out.println("After Undo: " + editor.getContent());
    }
}

4、是否存在缺陷和不足

  1. 如果备忘录对象占用大量内存,可能会导致资源消耗较大。
  2. 如果原发器类的内部状态包含对其他对象的引用,备忘录模式无法完全保护这些对象的封装性。

5、如何缓解缺陷和不足

  1. 精简备忘录:如果备忘录对象占用大量内存,可以考虑设计更加精简的备忘录对象,只保存必要的状态。
  2. 深拷贝:如果原发器类的内部状态包含对其他对象的引用,可以使用深拷贝技术来复制这些对象,保护对象的封装性。

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

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

相关文章

【数字图像处理】实验四 图像分割

一、实验内容&#xff1a; 1&#xff0e; 熟悉和掌握利用Matlab工具进行数字图像的读、写、显示等数字图像处理基本步骤。 2&#xff0e; 熟练掌握各种图像分割的基本原理及方法。 3&#xff0e; 能够从深刻理解图像分割&#xff0c;并能够思考拓展到一定的应用领域。 二、实验…

雷军1992年发表的计算机论文,强啊!

提起雷军&#xff0c;相信大家都非常熟悉了&#xff0c;90年代初毕业于武大计算机系&#xff0c;后来一路创业&#xff0c;现如今在相应领域的成就也有目共睹。 之前咱们这里也分享过雷军早年间写的文字博客&#xff0c;他曾在早期博客中讲述了自己的编程之路&#xff0c;以及当…

机器学习 | 概率图模型

见微知著&#xff0c;睹始知终。 见到细微的苗头就能预知事物的发展方向&#xff0c;能透过微小的现象看到事物的本质&#xff0c;推断结论或者结果。 概率模型为机器学习打开了一扇新的大门&#xff0c;将学习的任务转变为计算变量的概率分布。 实际情况中&#xff0c;各个变量…

一个简单的 HTTP 请求和响应服务——httpbin

拉取镜像 docker pull kennethreitz/httpbin:latest 查看本地是否存在存在镜像 docker images | grep kennethreitz/httpbin:latest 创建 deployment&#xff0c;指定镜像 apiVersion: apps/v1 kind: Deployment metadata:labels:app: httpbinname: mm-httpbinnamespace: mm-…

FPC柔性排线用什么胶水能固定到线路板上?

为了固定FPC柔性排线到线路板上&#xff0c;可以使用特殊用于电子组装的胶水。常用的胶水类型有&#xff1a; 1.氰基丙烯酸酯胶水&#xff08;Cyanoacrylate&#xff09; 被称为“超级胶水”或“快干胶水”。这种胶水对FPC通常有很好的附着力。 2.环氧树脂胶水 环氧树脂胶水…

C++之深拷贝和浅拷贝

目录 浅拷贝 深拷贝 赋值运算符重载的深拷贝 在学习C类和对象时我们学习了浅拷贝&#xff0c;本期我们将再次回顾浅拷贝并为大家讲述深拷贝的概念。 浅拷贝 在学习类和对象时我们学习了拷贝构造函数的概念&#xff0c;而且我们也知道&#xff0c;因为拷贝构造函数属于类的默…

02|用LangChain快速构建基于“易速鲜花”本地知识库的智能问答系统

02&#xff5c;用LangChain快速构建基于“易速鲜花”本地知识库的智能问答系统 项目及实现框架 我们先来整体了解一下这个项目。 项目名称&#xff1a;“易速鲜花”内部员工知识库问答系统。 项目介绍&#xff1a;“易速鲜花”作为一个大型在线鲜花销售平台&#xff0c;有自…

SpringCloudGateway网关处拦截并修改请求

SpringCloudGateway网关处拦截并修改请求 需求背景 老系统没有引入Token的概念&#xff0c;之前的租户Id拼接在请求上&#xff0c;有的是以Get&#xff0c;Param传参形式&#xff1b;有的是以Post&#xff0c;Body传参的。需要在网关层拦截请求并进行请求修改后转发到对应服务。…

软件工程快速复习(期末急救)

每个同学要假想自己是一个项目经理&#xff0c;去完成一个软件项目&#xff0c;比如医院管理系统&#xff0c;自动设备控制系统等&#xff0c;以面向结构的软件工程方法&#xff0c;说出完成项目的步骤&#xff0c;涉及到的具体技术。初步了解面向对象的方法的与面向结构的方法…

Linux网络编程——字节序

一、概念 字节序是指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序。 二、分类 字节序有两者常见序&#xff1a; 1. Big-Endian&#xff08;大端&#xff09;&#xff1a;高位字节排放在内存的低地址端&#xff0c;低位字节排放在内存的高地址端。如&#x…

量化交易学习笔记:XGBoost 在量化选股中的应用

一、引言 本篇文章通过借鉴传统机器学习算法——XGBoost——对相同的量价因子进行实验&#xff0c;方便与深度学习模型进行对比实践。 二、算法介绍 XGBoost 是在 Gradient Boosting&#xff08;梯度提升&#xff09;框架下实现的机器学习算法&#xff0c;全称为“极限梯度提…

图神经网络并在 TensorFlow 中实现

asokraju.medium.com 一、说明 本文将引导您了解图神经网络 (GNN) 并使用 TensorFlow 实现该网络。在后续的 文章中&#xff0c;我们讨论 GNN 的不同变体及其实现。这是一个分步计划&#xff1a; 图神经网络 (GNN) 的使用&#xff1a;我们首先讨论 GNN 是什么、它们如何工作以及…

论文阅读<MULTISCALE DOMAIN ADAPTIVE YOLO FOR CROSS-DOMAIN OBJECT DETECTION>

论文链接&#xff1a;https://arxiv.org/pdf/2106.01483v2.pdfhttps://arxiv.org/pdf/2106.01483v2.pdf 代码链接&#xff1a;GitHub - Mazin-Hnewa/MS-DAYOLO: Multiscale Domain Adaptive YOLO for Cross-Domain Object DetectionMultiscale Domain Adaptive YOLO for Cross…

[JS设计模式]Command Pattern

文章目录 举例说明优点缺点完整代码 With the Command Pattern, we can decouple objects that execute a certain task from the object that calls the method. 使用命令模式&#xff0c;我们可以将执行特定任务的对象与调用该方法的对象解耦。 怎么理解 执行特定任务的对…

【SpringBoot】之Security进阶使用

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是君易--鑨&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《SpringBoot开发之Security系列》。&#x1f3af…

解决 Linux git push 贡献者不同(没有出现绿点)的问题

第一步&#xff0c;通过下面的指令&#xff0c;修改 linux git 的配置文件&#xff1a; vi ~/.gitconfig会进入下图界面&#xff1a; 进入本地&#xff08;Windows&#xff09;中 git 的设置界面 复制 名称 和 Email 到 gitconfig 里&#xff0c;不要在末尾加 &#xff08;空…

直排轮滑教程4

蹬地 1&#xff0c;前面练习了蹬地的结构&#xff0c;知道蹬地方向&#xff0c;如何用力。下面来练习具体的蹬地的方法&#xff0c;轮滑蹬地有自己特点。 2&#xff0c;技术方法和特点&#xff1a;蹬地速度快&#xff0c;蹬地有弹性。似跳非跳蹬。 3&#xff0c;四轮着地。轮…

使用PE信息查看工具和Beyond Compare文件比较工具排查dll文件版本不对的问题

目录 1、问题说明 2、修改了代码&#xff0c;但安装版本还是有问题 3、使用PE信息查看工具查看音视频库文件&#xff08;二进制&#xff09;的时间戳 4、使用Beyond Compare比较两个库文件的差异 5、找到原因 6、最后 C软件异常排查从入门到精通系列教程&#xff08;专栏…

NFS原理详解

一、NFS介绍 1&#xff09;什么是NFS 它的主要功能是通过网络让不同的机器系统之间可以彼此共享文件和目录。 NFS服务器可以允许NFS客户端将远端NFS服务器端的共享目录挂载到本地的NFS客户端中。 在本地的NFS客户端的机器看来&#xff0c;NFS服务器端共享的目录就好像自己的磁…

【蓝桥杯】树的重心

树的重心 图的dfs模板 int dfs(int u) {st[u]true;for(int ih[u];i!-1;ine[i]){int je[i];if(!st[j]){dfs(j);}} }树是这样的。 邻接表&#xff1a; 1: 4->7->2->-1 2: 5->8->1->-1 3: 9->4->-1 4: 6->3->1->-1 5: 2->-1 6: 4->-1 7…