设计模式之状态模式(下)

3)共享状态
1.概述

在某些情况下,多个环境对象可能需要共享同一个状态,如果希望在系统中实现多个环境对象共享一个或多个状态对象,那么需要将这些状态对象定义为环境类的静态成员对象。

2.案例

背景:要求两个开关对象要么都处于开的状态,要么都处于关的状态,在使用时它们的状态必须保持一致,开关可以由开转换到关,也可以由关转换到开。

3.结构图

在这里插入图片描述

4.代码实现

开关类Switch

public class Switch {//定义三个静态的状态对象private static State state,onState,offState; private String name;public Switch(String name) {this.name = name;onState = new OnState();offState = new OffState();this.state = onState;}public void setState(State state) {this.state = state;}public static State getState(String type) {if (type.equalsIgnoreCase("on")) {return onState;}else {return offState;}}//打开开关public void on() {System.out.print(name);state.on(this);}//关闭开关public void off() {System.out.print(name);state.off(this);}
}

抽象状态类

abstract class State {public abstract void on(Switch s);public abstract void off(Switch s);
}

具体状态类

//打开状态
public class OnState extends State {public void on(Switch s) {System.out.println("已经打开!");}public void off(Switch s) {System.out.println("关闭!");s.setState(Switch.getState("off"));}
}//关闭状态
public class OffState extends State {public void on(Switch s) {System.out.println("打开!");s.setState(Switch.getState("on"));}public void off(Switch s) {System.out.println("已经关闭!");}
}

客户端类

public class Client {public static void main(String[] args) {// 开关1 和 开关2 共享了开、关的状态Switch s1,s2;s1=new Switch("开关1");s2=new Switch("开关2");s1.on();s2.on();s1.off();s2.off();s2.on();s1.on();	}
}
4)使用环境类实现状态转换
1.概述

由环境类Context作为一个状态管理器实现状态之间的转换。

2.优点

对于客户端来说,无须关心状态类,可以为环境类设置默认的状态类,而将状态的转换工作交给具体状态类或环境类来完成,具体的转换细节对于客户端而言是透明的。

3.缺点

增加新的具体状态类可能需要修改其他具体状态类或者环境类的源代码,否则系统无法转换到新增状态。

4.结构图

在这里插入图片描述

5.代码实现
//屏幕类
public class Screen {//枚举所有的状态,currentState表示当前状态private State currentState, normalState, largerState, largestState;public Screen() {this.normalState = new NormalState(); //创建正常状态对象this.largerState = new LargerState(); //创建二倍放大状态对象this.largestState = new LargestState(); //创建四倍放大状态对象this.currentState = normalState; //设置初始状态this.currentState.display();}public void setState(State state) {this.currentState = state;}//单击事件处理方法,封转了对状态类中业务方法的调用和状态的转换public void onClick() {if (this.currentState == normalState) {this.setState(largerState);this.currentState.display();}else if (this.currentState == largerState) {this.setState(largestState);this.currentState.display();}else if (this.currentState == largestState) {this.setState(normalState);this.currentState.display();}}
}//抽象状态类
abstract class State {public abstract void display();
}//正常状态类
public class NormalState extends State{public void display() {System.out.println("正常大小!");}
}//二倍状态类
public class LargerState extends State{public void display() {System.out.println("二倍大小!");}
}//四倍状态类
public class LargestState extends State{public void display() {System.out.println("四倍大小!");}
}

客户端类

public class Client {public static void main(String[] args) {Screen screen = new Screen();screen.onClick();screen.onClick();screen.onClick();}
}

注意

所有的状态转换操作都由环境类Screen实现,此时,环境类充当了状态管理器角色。

如果需要增加新的状态,例如“八倍状态类”,需要修改环境类,这在一定程度上违背了“开闭原则”,但对其他状态类没有任何影响。

5)总结
1.优点
  • 封装了状态的转换规则,在状态模式中可以将状态的转换代码封装在环境类或者具体状态类中,可以对状态转换代码进行集中管理,而不是分散在一个个业务方法中。

  • 将所有与某个状态有关的行为放到一个类中,只需要注入一个不同的状态对象即可使环境对象拥有不同的行为。

  • 允许状态转换逻辑与状态对象合成一体,而不是提供一个巨大的条件语句块,状态模式可以避免使用庞大的条件语句来将业务方法和状态转换代码交织在一起。

  • 可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。

2.缺点
  • 状态模式的使用必然会增加系统中类和对象的个数,导致系统运行开销增大。

  • 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱,增加系统设计的难度。

  • 状态模式对“开闭原则”的支持并不好,增加新的状态类需要修改那些负责状态转换的源代码,否则无法转换到新增状态;而且修改某个状态类的行为也需修改对应类的源代码。

3.适用场景
  • 对象的行为依赖于它的状态(如某些属性值),状态的改变将导致行为的变化。

  • 在代码中包含大量与对象状态有关的条件语句,这些条件语句的出现,会导致代码的可维护性和灵活性变差,不能方便地增加和删除状态,并且导致客户类与类库之间的耦合增强。

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

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

相关文章

vue3支持markdown显示格式

背景 公司内部文档大模型体验,需要一个demo做展示(做了好多demo了......),文档大模型的场景后台配置实体库、同义词、文档库等,其中文档库中有各种格式的文档,体验者让大模型写个脚本、以表格数据输出。页面…

helm介绍-部署helm私有仓库案例

helm介绍-部署helm私有仓库案例 helm介绍-部署helm私有仓库案例 在Kubernetes中部署容器云的应用也是一项有挑战性的工作,Helm就是为了简化在Kubernetes中安装部署容器云应用的一个客户端工具。通过helm能够帮助开发者定义、安装和升级Kubernetes中的容器云应用&a…

前端-vue项目debugger调试

一、前言 有的时候接受同事一个项目,用框架不一样,写的也不太规范,那么就需要打断点去学习改项目的流程了。 那么vue项目是如何debugger调试呢? 二、操作 大概理解一下,vue项目启动,大概是先启动框架&am…

手写前端控制并发任务

思路: 主要通过异步等待队列执行的原理。 当前执行的任务数达到最大值的时候,再继续执行的任务会放入等待队列里,直到当前任务执行结束后,减少一个当前任务数,并且判断队列中是否有任务,如果有则按顺序执…

高效进行文件夹批量改名,轻松实现英文到中文的翻译,让你的文件夹管理更高效!

在数字化时代,我们每天都在与无数的文件夹打交道。而管理这些文件夹,尤其是为它们命名,往往成为一项繁琐而耗时的任务。尤其是当文件夹名以英文命名时,对于非英语用户来说,理解和记忆都可能会成为一道难题。那么如何翻…

LeetCode 0924.尽量减少恶意软件的传播:连通块染色(以BFS为例)

【LetMeFly】924.尽量减少恶意软件的传播:连通块染色(以BFS为例) 力扣题目链接:https://leetcode.cn/problems/minimize-malware-spread/ 给出了一个由 n 个节点组成的网络,用 n n 个邻接矩阵图 graph 表示。在节点…

HarmonyOS4-数据持久化

轻量级preferences: 关系型数据库: 增删改: 查询语句: 具体详情代码可参与源码: 黑马大佬写的。 harmonyos-lessons: 黑马程序员B站HarmonyOS课程的基础篇代码部分

热门的软件测试趋势趋势分析

放眼全球,了解技术发展的边界和趋势,有助于组织和个人的发展及竞争力的提升,偶尔看到国外某网站的一篇文章,读来颇值得参考,简单翻译过来,分享一下。 也许这篇文章会给你一份指南,让你快速成长…

【电路笔记】-数字缓冲器

数字缓冲器 文章目录 数字缓冲器1、概述2、单输入数字缓冲器3、三态缓冲器3.1 有效“高”三态缓冲器3.2 有效“高”反相三态缓冲器3.3 有效“低”三态缓冲器3.4 有效“低”反相三态缓冲器4、三态缓冲器控制数字缓冲器和三态缓冲器可以在数字电路中提供电流放大以驱动输出负载。…

【uniapp】request请求函数封装,token、成功、失败等

1、封装http.ts //utils--->http.ts/*** 添加拦截器* 拦截request请求* 拦截uploadFile文件上传** TODO* 1、非http开头需要拼接地址* 2、请求超时* 3、添加小程序端请求头标识* 4、添加token请求头标识*/ import { useMemberStore } from /stores/index const member…

C语言学习/复习20

一、调试 1.实例1: 经调试,该代码因数组越界会死循环 二、优秀的代码 注意事项:assert()返回真假并决定是否报错 常量指针本质是指针,常量修饰它,表示这个指针是一个指向常量的指针(变量&#xff09…

MySQL 基础使用

文章目录 一、Navicat 工具链接 Mysql二、数据库的使用1.常用数据类型2. 建表 create3. 删表 drop4. insert 插入数据5. select 查询数据6. update 修改数据7. delete 删除记录truncate table 删除数据 三、字段约束字段1. 主键 自增delete和truncate自增长字段的影响 2. 非空…

Tomcat 获取客户端真实IP X-Forwarded-For

Tomcat 获取客户端真实IP X-Forwarded-For 代码实现&#xff1a; 在Host标签下面添加代码&#xff1a; <Valve className"org.apache.catalina.valves.RemoteIpValve" remoteIpHeader"x-forwarded-for" remoteIpProxiesHeader"x-forwarded-by&q…

Linux命令学习—Iptables 防火墙(上)

1.1、防火墙 1、防火墙的定义 所谓防火墙指的是一个由软件和硬件设备组合而成、在内部网和外部网之间、专用网与公共网之间的界面上 构造的保护屏障.是一种获取安全性方法的形象说法&#xff0c;它是一种计算机硬件和软件的结合&#xff0c;使 Internet 与 Intranet 之间建立起…

大功率Boost升压电路实例设计

项目介绍及参数要求 指标参数光伏额定功率: 4000W光伏最大输入电压: 350V光伏最小输入电压: 150V母线电压(Boost电路输出电压): 600V电流纹波率

野生动物保护视频AI智能监管方案,撑起智能保护伞,守护野生动物

一、背景 在当今世界&#xff0c;野生动物保护已经成为全球性的重要议题。然而&#xff0c;由于野生动物生存环境的不断恶化以及非法狩猎等活动的盛行&#xff0c;保护野生动物变得尤为迫切。为了更有效地保护野生动物&#xff0c;利用视频智能监管技术成为一种可行的方案。 …

Java springboot使用EasyExcel读Excel文件,映射不到属性值,对象属性值都是null

如果你的类上有这个注解&#xff0c;去掉火或注释掉就可以了 Accessors(chain true)解决方法

IO流高级流

前言 缓冲区能够提升输入输出的效率 虽然FileReader和FileWriter中也有缓冲区 但是BufferedReader和BufferWriter有两个非常好用的方法. 缓冲流 字节缓冲流 import java.io.*;public class BufferedStreamDemo {public static void main(String[] args) throws IOExceptio…

「JavaEE」线程

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;JavaEE &#x1f387;欢迎点赞收藏加关注哦&#xff01; 线程 &#x1f349;线程&#x1f34c;多线程&#x1f34c;线程与进程的联系&区别&#x1f34c;多线程编程&#x1f34c;创建线程&a…