Java设计模式中状态模式介绍/状态模式怎么使用

news2024/11/17 3:08:10

继续整理记录这段时间来的收获,详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用!

6.6 状态模式

6.6.1定义

对有状态的对象,把复杂的"判断逻辑"提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为

6.6.2 结构

  • 环境角色:称上下文,定义了客户程序需要的接口,维护一个当前状态,并将与状态相关的操作委托给当前状态对象来处理
  • 抽象状态角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为
  • 具体状态角色:实现抽象状态角色所对应的行为

6.6.3 案例(电梯状态)

  • 环境角色
public class Context {  
//    定义对应状态对象的常量  
    public final static OpeningState OPENING_STATE = new OpeningState();  
    public final static ClosingState CLOSING_STATE = new ClosingState();  
    public final static StopingState STOPING_STATE = new StopingState();  
    public final static RunningState RUNNING_STATE = new RunningState();  
//    定义一个当前电梯状态变量  
    private LiftState liftState;  
    public void setLiftState(LiftState liftState) {  
        this.liftState = liftState;  
//        设置当前状态对象中的Context对象  
        this.liftState.setContext(this);  
    }  
    public LiftState getLiftState() {  
        return liftState;  
    }  
    public void open() {  
        this.liftState.open();  
    }  
    public void close() {  
        this.liftState.close();  
    }  
    public void run() {  
        this.liftState.run();  
    }  
    public void stop() {  
        this.liftState.stop();  
    }  
}
  • 抽象状态类
public abstract class LiftState {  
//    声明环境状态类变量  
    public Context context;  
    public void setContext(Context context) {  
        this.context = context;  
    }  
//    电梯开启操作  
    public abstract void open();  
    //    电梯开启操作  
    public abstract void close();  
//    电梯运行操作  
    public abstract void run();  
    //    电梯关闭操作  
    public abstract void stop();  
}
  • 具体状态类
public class OpeningState extends LiftState {  
//    当前状态执行方法  
    @Override  
    public void open() {  
        System.out.println("电梯门开启。。。。");  
    }  
    @Override  
    public void close() {  
//        修改电梯状态,关门  
        super.context.setLiftState(Context.CLOSING_STATE);  
//        调用当前状态中的context对象中close  
        super.context.close();  
    }  
    @Override  
    public void run() {  
//        什么都不做,电梯门开了不能运行  
    }  
    @Override  
    public void stop() {  
//        什么都不做,门已开了,本身就是停了  
    }  
}
public class ClosingState extends LiftState {  
    //    当前状态执行方法  
    @Override  
    public void open() {  
        //        修改电梯状态,电梯门关了,可以再打开  
        super.context.setLiftState(Context.OPENING_STATE);  
//        调用当前状态中的context对象中close  
        super.context.open();  
    }  
    @Override  
    public void close() {  
        System.out.println("电梯门已关闭。。。。");  
    }  
    @Override  
    public void run() {  
        //        修改电梯状态,电梯门关了,可以再运行  
        super.context.setLiftState(Context.RUNNING_STATE);  
//        调用当前状态中的context对象中close  
        super.context.run();  
    }  
    @Override  
    public void stop() {  
        //        修改电梯状态,电梯门关了,就停下,不按楼层  
        super.context.setLiftState(Context.STOPING_STATE);  
//        调用当前状态中的context对象中close  
        super.context.stop();  
    }  
}
public class RunningState extends LiftState {  
    @Override  
    public void open() {  
//  运行中不能开门  
    }  
    @Override  
    public void close() {  
//  运行中不能关门,门已关  
    }  
    @Override  
    public void run() {  
        System.out.println("电梯运行中---");  
    }  
    @Override  
    public void stop() {  
//        运行停下来  
        super.context.setLiftState(Context.STOPING_STATE);  
        super.context.stop();  
    }  
}
public class StopingState extends LiftState {  
    @Override  
    public void open() {  
//        状态修改,停止状态可以开门  
        super.context.setLiftState(Context.OPENING_STATE);  
        super.context.open();  
    }  
    @Override  
    public void close() {  
//        停止状态可以关门  
        super.context.setLiftState(Context.CLOSING_STATE);  
        super.context.close();  
    }  
    @Override  
    public void run() {  
//        停止状态可以运行  
        super.context.setLiftState(Context.RUNNING_STATE);  
        super.context.run();  
    }  
    @Override  
    public void stop() {  
        System.out.println("电梯已经停止");  
    }  
}
  • 测试
    public static void main(String[] args) {  
//        创建环境角色对象  
        Context context = new Context();  
//        设置当前电梯状态  
        context.setLiftState(new RunningState());  
        context.open();  
        context.run();  
        context.close();  
        context.stop();  
    }
  • 结果
    ![[Pasted image 20230114225804.png]]
  • 类图![[Pasted image 20230114230220.png]]

6.6.4 优缺点

6.6.4.1 优点

  • 将所有与某个状态有关的行为放到一个类中,可以方便的增加新的状态,只需要改变对象状态即可改变对象行为
  • 允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语块

6.6.4.2 缺点

  • 会增加系统类和对象个数
  • 结构和实现比较复杂,若使用不当导致程序结构和代码的混乱
  • 对“开闭原则”支持不太好

6.6.5 使用场景

  • 当对象行为取决于它的状态,且它必须在运行时根据状态改变行为
  • 一个操作含有庞大的分支结构,且这些分支决定于对象状态时

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

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

相关文章

【C++】哈希表 | 闭散列 | 开散列 | unordered_map 和 unordered_set 的模拟实现

​🌠 作者:阿亮joy. 🎆专栏:《吃透西嘎嘎》 🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根 目录👉unordere…

Ubuntu20.04/22.04 安装 Arduino IDE 2.x

这周收到两片基于LGT8F328P LQFP32的Arduino Mini EVB, 机器上没有 Arduino 环境需要新安装, 正好感受一下新出的 Arduino IDE 2.x, 记录一下 Ubuntu 20.04/22.04 下安装 Arduino IDE 2.x 的过程. 下载解压 下载 访问 Arduino 的官网下载 https://www.arduino.cc/en/softwar…

2021-04-12

今天在练习自定义标题栏(Android初级开发(四)——补充3)的过程中遇到了隐藏系统自带标题栏的问题,现将几种去掉系统自带标题栏的方式做一总结。大体上可以分为两种方式,一种是修改xml文件(这种方…

第六层:继承

文章目录前情回顾继承继承的作用继承的基本语法继承方式公共继承保护继承私有继承继承中的对象模型继承中的构造和析构顺序继承中同名成员访问非静态成员静态成员多继承语法注意多继承中的对象模型多继承父类成员名相同菱形继承概念菱形继承出现的问题虚继承步入第七层本章知识…

【数据分析】(task3)数据重构

note 数据的合并:df自带的join方法是横向合并,append方法是纵向(上下)合并拼接;pd的merge方法是横向合并,然后用刚才的apend进行纵向合并。数据的重构:stack函数的主要作用是将原来的列转成最内…

Redis基本类型和基本操作

2.Redis常见命令 Redis是典型的key-value数据库,key一般是字符串,而value包含很多不同的数据类型: Redis为了方便我们学习,将操作不同数据类型的命令也做了分组,在官网( https://redis.io/commands &…

阿里云轻量服务器下>安装宝塔面板>安装使用Tomcat服务器>通过公网ip地址>直接访问网站目录下文件

第一步 阿里云开放Tomcat 8080端口号 和宝塔面板 8888端口 第二步 如果你的应用镜像 一开始在阿里云购买服务器时候没有选择宝塔应用镜像 先打开如下界面 将系统中应用镜像 确定更换为 宝塔面板镜像 第三步 请在应用详情中 走完紫色所框选的步骤 第四步 将上一步获取到的…

cadence SPB17.4 - allegro - align component by pin

文章目录cadence SPB17.4 - allegro - align component by pin概述笔记实验备注补充 - 2023_0120_2337ENDcadence SPB17.4 - allegro - align component by pin 概述 allegro自带的元件对齐, 默认是对齐元件中心的, 对齐后的效果是中心对齐. 但是为了走线能走的最短, 拉线方便…

2023年春节祝福第二弹——送你一只守护兔(下),CSS3 动画相关属性图例实例大全(82种),守护兔源代码免费下载

2023年春节祝福第二弹——送你一只守护兔(下) CSS3 动画相关属性图例实例大全(82种)、守护兔源代码免费下载 本文目录: 五、CSS3 动画相关属性实例大全 (1)、CSS3的动画基本属性 (2&#xf…

TCP/IP OSI七层模型

作者简介:一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页​​​​​​ 目录 前言 一.OSI七层模型 1.什么是OSI七层参考模型 2.七层每层分别的作用…

Spring热部署设置

手动热部署 热部署是指在不停止应用程序的情况下更新应用程序的功能。这样可以避免短暂的服务中断&#xff0c;并且可以更快地部署新的功能和修复问题。热部署通常适用于Web应用程序和服务器端应用程序。 在pom.xml中添加依赖&#xff1a; <dependency><groupId>…

cmake 02 hello_cmake

cmake 学习笔记 一个最小化的 cmake 项目 目录结构 F:\2023\code\cmake\hello_cmake>tree /f 卷 dox 的文件夹 PATH 列表 卷序列号为 34D2-6BE8 F:. │ CMakeLists.txt │ main.cpp │ └─.vscodelaunch.jsontasks.jsonF:\2023\code\cmake\hello_cmake>源码 main.c…

Java 集合 笔记

体系 Collection接口 List接口&#xff1a;按照顺序插入数据&#xff0c;可重复 ArrayList实现类&#xff1a;LinkedList实现类&#xff1a; Set接口&#xff1a;不可重复的集合 HashSet实现类 Queue接口&#xff1a;队列 LinkedList实现类ArrayBlockingQueue实现类PriorityQu…

Python CalmAn工具包安装及环境配置过程【Windows】

文章目录CalmAn简介安装要求我的设备1>CalmAn压缩包解压2>conda创建虚拟环境3>requirements依赖包配置&#xff08;包括tensorflow&#xff09;4>caiman安装(mamba install)5>caimanmanager.py install6>PyCharm添加解释器7>Demo演示8>遇到的问题CalmA…

DB SQL 转 ES DSL(支持多种数据库常用查询、统计、平均值、最大值、最小值、求和语法)...

1. 简介 日常开发中需要查询Elasticsearch中的数据时&#xff0c;一般会采用RestHighLevelClient高级客户端封装的API。项目中一般采用一种或多种关系型数据库(如&#xff1a;Mysql、PostgreSQL、Oracle等) NoSQL(如&#xff1a;Elasticsearch)存储方案&#xff1b;不同关系数…

【SAP Abap】X档案:SAP ABAP 中 AMDP 简介及实现方法

SAP ABAP 中 AMDP 简介及实现方法0、前言1、AMDP 简介1.1 代码下沉&#xff08;Code Pushdown&#xff09;1.2 AMDP 是托管数据库过程的容器1.3 AMDP 的优缺点1.4 几种数据库访问方式的区别1.5 几种数据库访问方式的选用1.6 使用的开发工具2、实现方法2.1 AMDP PROCEDURE&#…

Linux自带10种常用性能分析与监控工具

liunx的性能分析与监控这些问题是一个很重要的问题&#xff0c;我们需要解决这个问题就可以借助liunx中的一些工具来帮我们处理掉这个问题&#xff0c;以下将会讲一下目前liunx中常用自带的性能分析与监控工具 Linux自带10种常用性能分析与监控工具1.vmstat2.iostat3.iotop监控…

uniapp cli的使用

uniapp官方文档有很多地方写的不是很明白。写笔记还是非常有必要的。 cli入门 uniapp的cli分为两种&#xff1a;uni cli和hbuilder cli。下面是官方对于两者的定义。官方实际上是更推荐uni cli的。因为官方文档通篇都是介绍uni cli&#xff0c;也是优先介绍uni cli的。hbuild…

Linux系统之Bonding 网卡绑定配置方法

Linux系统之Bonding 网卡绑定配置方法一、检查本地系统环境1.检查系统版本2.查看服务器网卡二、创建网卡配置文件1.进入网卡配置文件目录2.拷贝eth0的网卡配置文件3.修改bond0网卡配置文件4.修改eth1网卡配置文件5.修改eth2网卡配置文件三、创建bonding的配置文件1.编辑bonding…

OneFlow v0.9.0正式发布

今天是 OneFlow 开源的第 903 天&#xff0c;OneFlow v0.9.0 正式发布。本次更新包含 640 个 commit&#xff0c;完整更新列表请查看链接&#xff1a;https://github.com/Oneflow-Inc/oneflow/releases/tag/v0.9.0&#xff0c;欢迎下载体验新版本&#xff0c;期待你的反馈。One…