Java设计模式——状态模式

2023-11-07

介绍状态模式

核心思想就是:当对象的状态改变时,同时改变其行为。也就是行为由其状态决定。

介绍
意图:允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。

主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。

何时使用:代码中包含大量与对象状态有关的条件语句。

如何解决:将各种具体的状态类抽象出来。

关键代码:通常命令模式的接口中只有一个方法。而状态模式的接口中有一个或者多个方法。而且,状态模式的实现类的方法,一般返回值,或者是改变实例变量的值。也就是说,状态模式一般和对象的状态有关。实现类的方法有不同的功能,覆盖接口中的方法。状态模式和命令模式一样,也可以用于消除 if…else 等条件选择语句。

应用实例: 1、打篮球的时候运动员可以有正常状态、不正常状态和超常状态。 2、曾侯乙编钟中,‘钟是抽象接口’,'钟A’等是具体状态,'曾侯乙编钟’是具体环境(Context)。

优点: 1、封装了转换规则。 2、枚举可能的状态,在枚举状态之前需要确定状态种类。 3、将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。 4、允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。 5、可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。

缺点: 1、状态模式的使用必然会增加系统类和对象的个数。 2、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。 3、状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码。

使用场景: 1、行为随状态改变而改变的场景。 2、条件、分支语句的代替者。

注意事项:在行为受状态约束的时候使用状态模式,而且状态不超过 5 个。

状态模式

我们通过自动洗衣机工作过程来描述一下状态模式使用。

简单起见,这里我们仅仅考虑【开始】-> 【工作】-> 【结束】,这三个状态。

下面先来看一下其UML的类图:

在这里插入图片描述

  • 抽象状态接口:State
public interface State {
    public void doJob(Washing washing);
}
  • 开始状态:Start
public class Start implements State {
    @Override
    public void doJob(Washing washing) {
        System.out.println("Start Washing Clothes!");
        washing.setState(new Work());
        washing.request();
    }
}
  • 工作状态:Work
public class Work implements State{
    @Override
    public void doJob(Washing washing) {
        System.out.println("Working Now!");
        washing.setState(new End());
        washing.request();
    }
}
  • 结束状态:End
public class End implements State{
    @Override
    public void doJob(Washing washing) {
        System.out.println("All Finished!");
        washing.setState(null);
    }
}
  • 洗衣机类:Washing
public class Washing {
    private State state = null;
    
    public void setState(State state) {
        this.state = state;
        if (state == null) {
            System.out.println("Current state: null!");
        }
        else {
            System.out.println("Current state: " + state.getClass().getName());
        }
    }
    
    public void request() {
        if (state != null) {
            state.doJob(this);
        }
    }
}
  • 演示(Client):
public class Demo {
    public static void main(String[] args) {
        Washing washing = new Washing();
        washing.setState(new Start());
        washing.request();
    }
}

结果:

Current state: state.Start
Start Washing Clothes!
Current state: state.Work
Working Now!
Current state: state.End
All Finished!
Current state: null!

washing中提供用户使用的主要接口。初始时,使用者使用一个状态来配置washing,然后便可对washing发送指令,后续不在需要用户直接于具体转态打交道。每个状态会自动控制向下一个状态转移,直到运行结束。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java设计模式——状态模式 的相关文章

随机推荐

  • WIN10去除磁盘写保护(只读属性)的步骤

    WIN10去除磁盘写保护 只读属性 的步骤 1 使用管理员权限进入win10的命令模式 使用系统搜索cmd 然后使用管理员模式打开 如下图 点击搜索 2 输入cmd 3 使用鼠标点击使用管理员身份打开 4 打开之后切换到C盘根目录 cd 这
  • 信号完整性分析基础知识之有损传输线、上升时间衰减和材料特性(一):为什么要关注损耗?

    一个具有极快上升沿的信号输入到真实传输线中 在从传输线输出的时候上升时间会很长 例如 一个上升时间为50ps的信号 在经过一段36inch长 50Ohm传输线后 上升时间增加到1ns 上升时间的退化是由于传输线的损耗 这也是引起码间干扰 i
  • TypeScript中的泛型(泛型函数、接口、类、泛型约束)

    一 泛型函数 TypeScript泛型是一种可以使代码具有更高的可重用性和泛化能力的特性 通过泛型 我们可以定义一种通用的类型或函数 使其能够应对多种类型的输入 泛型在类 函数 接口等多种场景下都可以使用 具体来说 在定义泛型函数时 我们可
  • 2022年SaaS发展趋势——私有本地化部署

    据麦肯锡 物联网 抓住加速机遇 报告预测 到2030年 物联网将在全球创造最高可达12 6万亿美元的经济价值 随着亚马逊 阿里云等云计算巨头不断加码投入 公有云IoT物联网平台因其低成本 易上手 高可靠等好处而被中小企业决策者广泛认可 然而
  • Vue中全局使用Spin组件

    如何全局使用 1 在man js引入Spin import Spin from ivew 2 将Spin挂载到Vue对象原型上 Vue prototype Spin Spin 3 在子组件调用 this Spin show
  • Python进阶:聊聊IO密集型任务、计算密集型任务,以及多线程、多进程

    https zhuanlan zhihu com p 24283040 IO密集型任务 VS 计算密集型任务 所谓IO密集型任务 是指磁盘IO 网络IO占主要的任务 计算量很小 比如请求网页 读写文件等 当然我们在Python中可以利用sl
  • prometheus - node_exporter - CPU利用率(入门基础)

    node exporter CPU 一 获取 各种状态 CPU 的使用率 二 所用函数 1 increase time 增量函数 2 sum 叠加函数 3 by 拆分函数 二 计算 CPU 每分钟的 使用率 思路 步骤如下 1 计算CPU的
  • TCP三次握手与四次挥手

    本文主要讲述的是 1 面试官在问到TCP IP三次握手原理 以及为什么要三次握手 两次握手带来的不利后果 2 面试官问TCP IP四次挥手原理 为什么要四次挥手 TCP IP三次握手原理 首先 给张图片 建立TCP IP三次握手的直观印象
  • 计算机专业毕业设计题目大全文库,计算机专业毕业设计论文题目.doc

    计算机专业毕业设计论文题目 doc 由会员分享 可在线阅读 更多相关 计算机专业毕业设计论文题目 doc 43页珍藏版 请在金锄头文库上搜索 1 计计 算算 机机 专专 业业 毕毕 业业 设设 计计 论论 文文 目目 录录 ASP 类计算机
  • 最大股票收益问题(数组最大差问题)

    最大股票收益问题 数组最大差问题 问题描述 给定一个数组 存储着按照时间排序的股票价格 第 i i个位置的元素为第ii次交易时的股票价格 现假设只允许你进行一次买 然后在某一时刻卖出 单只股票 请设计算法 求解你可能获得的最大收益 如果股价
  • Windows下安装Redis

    打开redis中文官方网站 发现都需要安装在linux上 Windows版本的前往github上下载 地址 https github com microsoftarchive redis releases 由于需要外网比较难下载 所以放一个
  • 使用Fragment实现底部菜单的切换

    在做android项目的时候 经常会遇到底部有几个菜单 点击之后 页面上面部分需要展示不同的内容 如下图 在我的这个例子里面 采用了Fragment来展示点击下面菜单之后的不同数据 开发步骤 1 分析页面布局 页面分成底部菜单和上面的展示区
  • 哈工大计算机网络MOOC作业题解答

    第一周 如图所示网络 A在t 0时刻开始向C发送一个2Mbits的文件 B在t 0 1 e秒 e为无限趋近于0的小正实数 向D发送一个1Mbits的文件 忽略传播延迟和结点处理延迟 请回答下列问题 如果图中网络采用存储 转发方式的报文交换
  • conda SSL错误 SSLError,爬虫应用总结

    1 conda SSL错误 SSLError Can t connect to HTTPS URL because the SSL module is not available 解决办法 使用conda环境来运行爬虫程序 因为无法使用电脑
  • 通过小皮面板启动后端php项目和数据库

    1 启动php项目开启后端网站 可去官网下载 下载后就能使用了 官网地址 小皮面板 phpstudy 让天下没有难配的服务器环境 下载完成后打开 php项目需要启动apache或nginx 目前我用的是nginx 可以更改一些配置 先下载后
  • Linux 定期清理内存脚本

    bin bash 清理内存脚本 释放 PageCache echo echo 1 gt proc sys vm drop caches sudo sh 释放 dentries 和 inodes echo echo 2 gt proc sys
  • 5个用于图像处理的Python库

    图像处理是操纵图像以从中提取特征的现象 在当今计算机视觉和深度学习的世界中 大量使用不同的图像处理算法对图像数据集进行边缘检测 识别和分类 有时 这些算法也会逐帧应用于视频 以从中提取特征 在今天的文章中 我们将介绍5个最好的Python库
  • 如何计算单个region server能支持的最大region数

    虽理论上说单个region server能支持最多1000个region 但实际上是不太可能的 RegionServer维护Master分配给它的region 处理对这些region的IO请求 负责切分在运行过程中变得过大的region r
  • git提交代码弹出windows安全中心

    不知道有没有uu和我一样 第一次用git提交代码到码云时 前面都挺好的 突然最后一步来个windows安全中心 我就上网搜 说啥都都有 就是一个用户名密码呗 我想 然后按照网上的方法是github的用户名和密码 我当时还奇怪了这和githu
  • Java设计模式——状态模式

    文章目录 介绍状态模式 状态模式 介绍状态模式 核心思想就是 当对象的状态改变时 同时改变其行为 也就是行为由其状态决定 介绍 意图 允许对象在内部状态发生改变时改变它的行为 对象看起来好像修改了它的类 主要解决 对象的行为依赖于它的状态