行为型-状态模式(State Pattern)
概述
状态模式是一种行为设计模式,它可以让对象在内部状态改变时改变它的行为。简而言之,状态模式允许对象在不同状态下更改其行为,而不需要通过使用大量的条件语句进行手动更改。
优点:
- 状态模式将与特定状态相关的行为分散到不同的状态类中,使得代码更加模块化并且易于理解和维护。
- 状态模式符合开放封闭原则(Open-Closed Principle),当需要新增一种状态时,可以通过添加一个新的状态类来扩展系统,而不需要修改已有的代码。
- 状态模式将状态转换逻辑封装在状态类中,使得可以在不同的状态类中实现不同的状态转换规则,从而实现更灵活的状态转换逻辑。
缺点:
- 状态类的数量可能会随着状态的增加而增加,导致系统中类的数量增加,增加了代码的复杂性和理解难度。
- 状态模式要求对象具有较为复杂的内部状态转换逻辑,如果只有少量的状态转换,使用状态模式可能会显得过于繁琐。
使用场景:
- 当一个对象的行为与其状态相关,并且在不同状态下行为发生变化时,可以考虑使用状态模式。例如,订单在不同状态下有不同的行为,可以使用状态模式来封装每个状态的行为。
- 当需要提供对象的历史记录和撤销功能时,状态模式可以很好地实现。例如,文本编辑器中的编辑历史记录、Web浏览器中的前进和后退功能等。
示例
假设我们正在开发一个电子商务平台,需要实现订单状态的管理。订单的状态可以有多种,例如待支付、已支付、已发货、已完成等。不同的状态下,订单的行为也不同。
首先,我们定义订单状态接口OrderState,并在接口中定义订单的行为:
public interface OrderState {void pay(Order order);void deliver(Order order);void complete(Order order);
}
然后,我们实现具体的订单状态类,例如待支付状态PendingPaymentState、已支付状态PaidState、已发货状态ShippedState和已完成状态CompletedState:
public class PendingPaymentState implements OrderState {@Overridepublic void pay(Order order) {System.out.println("订单已支付");order.setState(new PaidState());}@Overridepublic void deliver(Order order) {System.out.println("订单未支付,不能发货");}@Overridepublic void complete(Order order) {System.out.println("订单未支付,不能完成");}
}public class PaidState implements OrderState {@Overridepublic void pay(Order order) {System.out.println("订单已支付");}@Overridepublic void deliver(Order order) {System.out.println("订单已发货");order.setState(new ShippedState());}@Overridepublic void complete(Order order) {System.out.println("订单未发货,不能完成");}
}public class ShippedState implements OrderState {@Overridepublic void pay(Order order) {System.out.println("订单已支付");}@Overridepublic void deliver(Order order) {System.out.println("订单已发货");}@Overridepublic void complete(Order order) {System.out.println("订单已完成");order.setState(new CompletedState());}
}public class CompletedState implements OrderState {@Overridepublic void pay(Order order) {System.out.println("订单已支付,不能重新支付");}@Overridepublic void deliver(Order order) {System.out.println("订单已完成,不能发货");}@Overridepublic void complete(Order order) {System.out.println("订单已完成");}
}
接下来,我们定义订单类Order,并在类中保存订单的状态和执行订单相关的行为:
public class Order {private OrderState state;public Order() {this.state = new PendingPaymentState();}public void setState(OrderState state) {this.state = state;}public void pay() {state.pay(this);}public void deliver() {state.deliver(this);}public void complete() {state.complete(this);}
}
现在,我们可以创建订单对象,并根据不同的状态执行订单的行为:
public class StateExample {public static void main(String[] args) {// 创建订单对象Order order = new Order();// 执行订单的行为order.pay();order.deliver();order.complete();}
}
运行结果
订单已支付
订单未支付,不能发货
订单未支付,不能完成
相关文章:
行为型-状态模式(State Pattern)
概述 状态模式是一种行为设计模式,它可以让对象在内部状态改变时改变它的行为。简而言之,状态模式允许对象在不同状态下更改其行为,而不需要通过使用大量的条件语句进行手动更改。 优点: 状态模式将与特定状态相关的行为分散到…...
大厂领导为什么喜欢跨层与下属聊天
作为一个在大厂里面浸淫十几年的loser,平时主要精力没用在技术提升上,对于大厂的人情世故各类八卦倒是研究的透彻。 如果你细心观察,会发现一些大的公司里面,领导喜欢跨层与下属去沟通聊天,我待过几家比较大的公司&am…...
Android 面试题 避免OOM(内存优化)三
🔥 OOM介绍(out of memory 内存溢出)🔥 Android和java中都会出现由于不良代码引起的内存泄露,为了使Android应用程序能够快速高效的运行,Android每个应用程序都会有专门Dalvik虚拟机实例来运行,…...
SpringBoot集成Lock4j 底层使用Redission 实现分布锁
Lock4j 在分布式系统中,实现锁的功能对于保证数据一致性和避免并发冲突是非常重要的。Lock4j是一个简单易用的分布式锁框架,而Redisson是一个功能强大的分布式解决方案,可以与Lock4j进行集成。 操作步骤 第一步:添加依赖 首先&…...
TortoiseSVN操作使用
说明 SVN常用于程序代码版本控制,由于业务需求需将生产资料通过SVN进行管控,涉及人员众多,权限分支管理需要细化,特此记录SVN的学习操作. 前言 版本控制是管理信息修改的艺术,它一直是程序员最重要的工具,程序员经常会花时间作出小的修改, 然…...
第五篇-ChatGLM2-6B模型下载
下载chatglm2-6b模型文件 https://huggingface.co/THUDM/chatglm2-6b方法一:huggingface页面直接点击下载 一个一个下载,都要下载方法二:snapshot_download下载文件 可以使用如下代码下载 创建下载环境 conda create --name hfhub pytho…...
【Matlab】基于长短期记忆网络的数据分类预测(Excel可直接替换数据)
【Matlab】基于长短期记忆网络的数据分类预测(Excel可直接替换数据) 1.模型原理2.数学公式3.文件结构4.Excel数据5.分块代码6.完整代码7.运行结果1.模型原理 “基于长短期记忆网络的数据分类预测”是一种利用长短期记忆网络(Long Short-Term Memory, LSTM)进行数据分类任务…...
C++网络编程 TCP套接字基础知识,利用TCP套接字实现客户端-服务端通信
1. TCP 套接字编程流程 1.1 概念 流式套接字编程针对TCP协议通信,即是面向对象的通信,分为服务端和客户端两部分。 1.2 服务端编程流程: 1)加载套接字库(使用函数WSAStartup()),创建套接字&…...
苍穹外卖-day07
苍穹外卖-day07 本项目学自黑马程序员的《苍穹外卖》项目,是瑞吉外卖的Plus版本 功能更多,更加丰富。 结合资料,和自己对学习过程中的一些看法和问题解决情况上传课件笔记 视频:https://www.bilibili.com/video/BV1TP411v7v6/?sp…...
简化Java单元测试数据
用EasyModeling简化Java单元测试 EasyModeling 是我在2021年圣诞假期期间开发的一个 Java 注解处理器,采用 Apache-2.0 开源协议。它可以帮助 Java 单元测试的编写者快速构造用于测试的数据模型实例,简化 Java 项目在单元测试中准备测试数据的工作&…...
P1041 [NOIP2003 提高组] 传染病控制
题目 题目背景 本题是错题,后来被证明没有靠谱的多项式复杂度的做法。测试数据非常的水,各种玄学-做法都可以通过,不代表算法正确。因此本题题目和数据仅供参考。 近来,一种新的传染病肆虐全球。蓬莱国也发现了零星感染者&#…...
TypeScript -- 基础类型
文章目录 TypeScript -- 基础类型let 和 const基本类型写法布尔类型 -- boolean数字类型 -- number字符串类型 -- string数组类型元组类型枚举类型 -- enum任意类型 -- any空值 -- voidNull 和 Undefined不存在的类型 -- never对象 -- object类型断言 TypeScript – 基础类型 1…...
Cookie 与 Session 的作用及区别、结合使用
Cookie的作用 在网站中,http请求是无状态的。也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。 Cookie的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(Cookie&a…...
【Redis】面试题
1. 为什么要用缓存 1. 提高系统的读写性能。 2. 减轻数据库的压力,防止大量的请求到达数据库,让数据库压力剧增,拖垮数据库。redis数据存储在内存中,高效的数据结构,读写数据比数据库快。 将热点数据存储在redis当中&…...
(学习笔记-硬件结构)CPU如何执行程序?
冯诺依曼模型 冯诺依曼模型主要由五部分组成:运算器、控制器、存储器、输入设备、输出设备。 控制器(Control Unit):从内存中取指令、翻译指令、分析指令,然后根据指令的内存向有关部件发送控制命令,控制相…...
curl: (26) Failed to open/read local data from file/application
Windows10、Windows环境用curl命令上传文件报错: curl: (26) Failed to open/read local data from file/application假设我要上传的文件目录是: F:\我的下载\test.xlsx 错误写法1:使用单引号 curl -X POST "https://xxx/upload&quo…...
2023年深圳杯数学建模 D题 基于机理的致伤工具推断
致伤工具的推断一直是法医工作中的热点和难点。由于作用位置、作用方式的不同,相同的致伤工具在人体组织上会形成不同的损伤形态,不同的致伤工具也可能形成相同的损伤形态。致伤工具品种繁多、形态各异,但大致可分为两类:锐器&…...
DMA传输原理与实现详解(超详细)
DMA(Direct Memory Access,直接内存访问)是一种计算机数据传输方式,允许外围设备直接访问系统内存,而无需CPU的干预。 文章目录 Part 1: DMA的工作原理配置阶段:数据传输阶段: Part 2: DMA数据…...
【《React Hooks实战》——指导你使用hook开发性能优秀可复用性高的React组件】
使用React Hooks后,你很快就会发现,代码变得更具有组织性且更易于维护。React Hooks是旨在为用户提供跨组件的重用功能和共享功能的JavaScript函数。利用React Hooks, 可以将组件分成多个函数、管理状态和副作用,并且不必声明类即…...
Ajax详细讲解
Ajax(Asynchronous JavaScript And XML)即异步 JavaScript 和 XML,是一组用于在网页上进行异步数据交换的 Web 开发技术,可以在不刷新整个页面的情况下向服务器发起请求并获取数据,然后将数据插入到网页中的某个位置。…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
