大话设计模式——17.状态模式(State Pattern)

简介

对象的行为依赖于它的状态(属性),可以根据状态的改变而改变相关行为。

UML图:

在这里插入图片描述

应用场景:
  • 对象的行为取决于其状态,并且必须要在运行时刻根据状态而改变行为
  • 代码中包含大量与对象状态有关的条件语句

示例

上午、下午、晚上工作的状态

  1. 上下文对象:
public class Work {/*** 工作状态*/private State state;/*** 当前时间*/private int hour;/*** 工作是否完成*/private boolean isFinished;public Work() {// 初始化操作this.state = new MorningState();}public void writeProgram() {state.writeProgram(this);}public State getState() {return state;}public void setState(State state) {this.state = state;}public int getHour() {return hour;}public void setHour(int hour) {this.hour = hour;}public boolean isFinished() {return isFinished;}public void setFinished(boolean finished) {isFinished = finished;}
}
  1. 状态
public interface State {void writeProgram(Work work);
}
public class MorningState implements State {@Overridepublic void writeProgram(Work work) {if (work.getHour() < 12) {System.out.println("当前时间:" + work.getHour() + ",干劲十足!");} else {work.setState(new NoonState());work.writeProgram();}}
}
public class NoonState implements State {@Overridepublic void writeProgram(Work work) {if (work.getHour() < 13) {System.out.println("当前时间:" + work.getHour() + ",好饿,开始干饭!");} else {work.setState(new AfternoonState());work.writeProgram();}}
}
public class AfternoonState implements State {@Overridepublic void writeProgram(Work work) {if (work.getHour() < 18) {System.out.println("当前时间:" + work.getHour() + ",开始上班,有点疲惫!");} else {work.setState(new EveningState());work.writeProgram();}}
}
public class EveningState implements State {@Overridepublic void writeProgram(Work work) {if (!work.isFinished()) {System.out.println("当前时间:" + work.getHour() + ",又要加班");} else {System.out.println("当前时间:" + work.getHour() + ",下班啦!");}}
}
  1. 运行
public class Main {public static void main(String[] args) {Work work = new Work();// 上午work.setHour(9);work.writeProgram();// 中午work.setHour(12);work.writeProgram();// 下午work.setHour(16);work.writeProgram();// 晚上work.setHour(18);
//        work.setFinished(true);work.writeProgram();}
}

在这里插入图片描述

总结

  • 优点
    • 只需改变对象的状态,就可改变对象的行为
    • 多个环境对象共享一个状态对象,可以减少系统中对象的个数
  • 缺点
    • 增加系统类和对象的个数
    • 使用不当将造成程序结构和代码的混乱
    • 不符合开闭原则,新增状态需要修改源码

VS 策略模式

  • 状态模式重在各个状态之间的切换从而有不同的行为,策略模式重在根据具体情况选择策略不涉及状态的切换
  • 状态模式不同状态做不同的事情且不能相互替换,策略模式解决的都是同一件事

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

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

相关文章

4月10日(信息差)

快捷新闻&#xff1a; &#x1f396; 素材来源官方媒体/网络新闻 &#x1f384; 地震预警App被曝收10元年费&#xff0c;回应称仅限苹果系统 &#x1f30d; 2024清明档首日票房破2亿 &#x1f30b; 浙江省杭州市余杭区设立2亿元网络微短剧发展基金 &#x1f381; 抖音拟以超 7…

oracle EXP-00028: 无法打开用于写入的 expdate.dmp

用exp备份带日期格式的文件名,命令如下: exp erpsys/12345678mytestdafilee:\backup\erpsys_mytestda_%date:~0,10%.dmp loge:\backup\erpsys_mytestda_%date:~0,10%.log rowsn buffer65536000 ownererpsys 成功执行后文件名字应如下: dmp文件是erpsys_mytestda_2012-06-13.…

小狐狸转账失败,提示gas费过高

做web3开发的时候&#xff0c;明明自己小狐狸里还有2.15的代币&#xff0c;但页面我要转出2.1的时候&#xff0c;明明是够的&#xff0c;而且使用小狐狸提示gas费用是21000&#xff0c;这已经是最小的了&#xff0c;但网页转出到其他账户总是提示失败。而且这个错误非常不好捕获…

Sqlserver格式化日期

使用CONVERT函数格式化日期&#xff1a; CONVERT函数允许你将日期/时间值转换为特定的字符串格式。它接受三个参数&#xff1a;转换的目标数据类型&#xff08;通常是一个字符串类型&#xff09;、要转换的表达式&#xff08;日期或时间值&#xff09;和样式代码。 示例&#x…

软考系规图文领读第1章:还是那碗温白开

第1章信息系统综合知识一共有4部分内容&#xff0c;分别是信息的定义和属性、信息化、信息系统和IT战略。这4部分的主体在第2部分的信息化和第3部分的信息系统。 和中项、高项都大同小异&#xff0c;都是从信息系统知识开始&#xff0c;越来越像一碗没有任何滋味的温白开&#…

使用OMP复原一维信号(MATLAB)

参考文献 https://github.com/aresmiki/CS-Recovery-Algorithms/tree/master MATLAB代码 %% 含有噪声 % minimize ||x||_1 % subject to: (||Ax-y||_2)^2<eps; % minimize : (||Ax-y||_2)^2lambda*||x||_1 % y传输中可能含噪 yyw % %% clc;clearvars; close all; %% 1.构…

【Redis】底层跳表实现

先巩固Redis的数据类型以及底层的数据结构&#xff1a; ZSet&#xff08;有序集合&#xff09;可以使用两种不同的内部数据结构来表示&#xff1a;压缩列表&#xff08;ziplist&#xff09;和跳跃表&#xff08;skiplist&#xff09;。 跳表是redis底层SortedSet(ZSet)的数据…

深入理解nginx realip模块[上]

目录 1. 引言2. Real IP模块的使用2.1 启用Real IP模块2.2 配置Real IP模块2.2.1 配置指令2.2.2 举例 3. 变量的使用 深入理解nginx realip模块[上] 深入理解nginx realip模块[下] 1. 引言 nginx 的 Real IP 模块用于解决代理服务器转发请求到nginx上时可能出现的 IP 地址问题…

python使用leveldb

LevelDB 是由 Google 开发的一个快速的键值存储库&#xff0c;提供了一个持久化的有序映射&#xff0c;非常适合用作简单的高性能数据库。 安装 Plyvel 首先&#xff0c;使用 pip3 来安装 plyvel pip3 install plyvel基本用法 接下来&#xff0c;介绍使用 plyvel 来操作 Le…

C++11 如何优雅地封装线程库以实现多线程编程

在C11标准中&#xff0c;多线程编程被正式纳入语言规范&#xff0c;通过引入 <thread> 头文件&#xff0c;C为开发者提供了一套统一且高效的线程API。std::thread 是 C11 标准库中用于创建和管理线程的核心类。本文将详细介绍C11是如何封装Thread库&#xff0c;以及如何通…

QT:信号与槽

作业&#xff1a; 完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳转到其他界面 如果账号和…

使用axios进行前后端数据传输

最近在和朋友合作写一个新的项目&#xff0c;前后端进行了分离&#xff0c;既然是分离的&#xff0c;肯定需要交互&#xff0c;今天这篇文章详细介绍一下数据交互的一种常见方式&#xff1a;使用axios,希望对大家有所帮助。 前端&#xff1a;以LoginPage.vue登录页面为例&…

HarmonyOS实战开发-如何实现电话服务中发送短信的功能。

介绍 本示例使用ohos.telephony.sms 接口展示了电话服务中发送短信的功能。 效果预览 使用说明&#xff1a; 首页点击创建联系人&#xff0c;弹框输入联系人姓名和电话&#xff0c;点击确定按钮后&#xff0c;联系人列表中添加该联系人;点击管理&#xff0c;该按钮变成取消&…

同步压缩理论

参考 在频率方向进行能量重新分配&#xff08;分配到中心&#xff09; 时频重排

【Rust】——改进I/O项目

&#x1f4bb;博主现有专栏&#xff1a; C51单片机&#xff08;STC89C516&#xff09;&#xff0c;c语言&#xff0c;c&#xff0c;离散数学&#xff0c;算法设计与分析&#xff0c;数据结构&#xff0c;Python&#xff0c;Java基础&#xff0c;MySQL&#xff0c;linux&#xf…

【算法基础】选择排序与冒泡排序的思想与实现

文章目录 1. 选择排序1.1 思想1.2 实现 2. 冒泡排序2.1 思想2.2 实现 1. 选择排序 1.1 思想 选择排序的思想很简单&#xff0c;如上图所示。在每一次遍历子数组的过程中&#xff0c;选择最小的和子数组的第一位交换。子数组的选择从一开始的整个数组&#xff0c;到后面范围逐渐…

C++的stack和queue类(一):适配器模式、双端队列与优先级队列

目录 基本概念 适配器模式 stack.h test.cpp 双端队列-deque 仿函数 优先级队列 基本概念 1、stack和queue不是容器是容器适配器&#xff0c;它们没有迭代器 2、stack的quque的默认容器是deque&#xff0c;因为&#xff1a; stack和queue不需要遍历&#xff0…

保姆级教程带你实现HarmonyOS手语猜一猜元服务(三)

&#x1f680;四、元服务代码分析 &#x1f50e;1.元服务代码结构介绍 AppScope中存放应用全局所需要的资源文件。entry是应用的主模块&#xff0c;存放HarmonyOS应用的代码、资源等。oh_modules是工程的依赖包&#xff0c;存放工程依赖的源文件。build-profile.json5是工程级…

FreeRTOS学习 -- FreeRTOSConfig.h介绍

一、FreeRTOSConfig.h文件 FreeRTOS 的系统配置文件为 FreeRTOSConfig.h&#xff0c;在此配置文件中可以完成 FreeRTOS 的裁剪和配置。 /*FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.All rights reservedVISIT http://www.FreeRTOS.org TO ENSURE YOU AR…

Android Studio修改项目包名

1.第一步&#xff0c;项目结构是这样的&#xff0c;3个包名合在了一起&#xff0c;我们需要把每个包名单独展示出来 2.我们点击这个 取消选中后的包名结构是这样的&#xff0c;可以看到&#xff0c;包名的每个文件夹已经展示分开了&#xff0c;现在我们可以单独对每个包名文件夹…