Java行为型模式(状态模式)实现方式与测试方法

一、状态模式实现方式

  1. 核心结构
  • 状态接口(State):定义状态相关的行为方法。
  • 具体状态类(ConcreteState):实现状态接口,封装特定状态下的逻辑。
  • 上下文类(Context):维护当前状态引用,委托请求给当前状态对象处理。
  1. 基础实现示例(以电梯控制为例)
// 状态接口
public interface ElevatorState {void handle(ElevatorContext context);
}
// 具体状态类:停止状态
public class StopState implements ElevatorState {@Overridepublic void handle(ElevatorContext context) {System.out.println("电梯已停止");context.setState(new RunningState()); // 切换状态}
}
// 上下文类
public class ElevatorContext {private ElevatorState state;public ElevatorContext(ElevatorState initialState) {this.state = initialState;}public void setState(ElevatorState state) {this.state = state;}public void request() {state.handle(this); // 委托处理}
}
  1. 高级实现技巧
  • 状态内部维护上下文:允许状态类直接操作上下文属性(如订单状态流转)。
  • 状态工厂优化:集中管理状态对象,避免重复创建。
  • 状态共享(单例模式):适用于无状态对象(如红绿灯状态)。

二、测试方法与策略

  1. 测试目标
  • 验证状态切换的正确性(如订单从“待支付”到“已发货”)。
  • 确保每个状态下的行为符合预期(如电梯停止时禁止移动)。
  1. 单元测试工具
    使用Mockito框架模拟依赖对象,隔离测试环境:
import static org.mockito.Mockito.*;
// 测试订单状态切换
public class OrderTest {@Testpublic void testOrderStateTransition() {Order order = new Order();OrderState initialState = mock(NewState.class);order.setState(initialState);// 模拟支付操作触发状态切换order.pay();verify(initialState).next(order); // 验证状态转换assertEquals(PaidState.class, order.getState().getClass());}
}
  1. 关键测试场景
  2. 状态转换验证
    使用verify()检查状态切换方法是否按预期调用。
    verify(context, times(1)).setState(any(RunningState.class));
    
  3. 行为逻辑验证
    结合断言(JUnit/Hamcrest)验证输出结果:
    assertThat(outputStream.toString(), containsString("电梯已停止"));
    
  4. 异常处理测试
    模拟非法状态操作(如未支付时尝试发货):
    assertThrows(IllegalStateException.class, () -> order.deliver());
    
  5. 参数化测试
    覆盖所有状态组合,减少重复代码:
@ParameterizedTest
@EnumSource(ElevatorState.class)
void testAllStates(ElevatorState state) {ElevatorContext context = new ElevatorContext(state);context.request();// 验证状态转换逻辑
}

三、测试最佳实践

  1. 独立性:每个测试用例初始化独立上下文,避免状态污染。
  2. 模拟外部依赖:用Mockito替代数据库或网络请求(如模拟订单支付接口)。
  3. 覆盖率:确保覆盖所有状态转换路径(如红灯→绿灯→黄灯→红灯)。

四、常见问题与解决方案

问题解决方案
状态切换未触发检查状态类是否正确调用context.setState()
测试用例间依赖使用@Before注解重置上下文状态。
状态转换逻辑遗漏通过状态机工具(如Spring StateMachine)可视化验证转换规则。

五、总结

状态模式通过对象化状态与委托机制实现了行为与状态的解耦,而单元测试则通过模拟框架与断言验证确保了状态转换的可靠性。实际开发中,结合Mockito进行隔离测试,可显著提升代码质量与维护效率。

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

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

相关文章

MISRA C-2012准则之标准C环境准则

目录 1.标准C环境准则 错误示例1:未定义行为(整数溢出) 错误示例2:未指定行为(函数调用顺序) 错误示例3:语言扩展(GCC内置函数) 错误示例4:关键未指定行…

26、鸿蒙Harmony Next开发:ArkTS并发(Promise和async/await和多线程并发TaskPool和Worker的使用)

目录 异步并发 (Promise和async/await) Promise async/await 多线程并发 多线程并发模型 内存共享模型 Actor模型 TaskPool TaskPool运作机制 TaskPool注意事项 Concurrent装饰器 装饰器说明 装饰器使用示例 TaskPool扩缩容机制 扩容机制 缩容机制 Worker Wo…

[IRF/Stack]华为/新华三交换机堆叠配置

堆叠的三大优势 提高资源利用率&#xff0c;获得更高的转发性能、链路带宽降低网络规划的复杂度、方便网络的管理降低故障对业务的影响时间 堆叠的两个需求 设备型号必须统一系统版本必须统一 华三堆叠案例&#xff1a;#### S6850_1 <H3C>sy [H3C]undo in en [H3C]sy SW…

融智兴科技: RFID超高频洗涤标签解析

在纺织品租赁与管理领域&#xff0c;布草、工服、医护织物等物品的流转追踪一直是运营管理的核心挑战。传统管理方式依赖人工计数与条码扫描&#xff0c;存在效率低下、差错率高、损耗严重等问题&#xff0c;尤其在工业洗涤环境下&#xff0c;纸质标签易损坏、识别率低。融智兴…

从平面到时空:地图故事的时空叙事与沉浸式阅读

朋友们&#xff0c;在工作中你是否也遇到过这些令人头疼的挑战&#xff1f;当项目汇报时总觉得表达不够精彩&#xff0c;方案讲解时听众总是一头雾水&#xff0c;制作应急预案时更是无从下手&#xff1f;别担心&#xff01;今天我要向大家介绍一个超级实用的解决方案——地图故…

自动控制原理知识地图:舵轮、路径与导航图

掌握自控原理的关键&#xff0c;在于看清那棵枝繁叶茂的“知识树”——从根部的数学模型&#xff0c;到主干的分析方法&#xff0c;直至顶端的系统设计。作为一名自动化专业学生&#xff0c;你是否曾在深夜里面对劳斯判据和奈奎斯特图感到深深的恐惧&#xff1f;作为初入行的工…

Flutter在Android studio运行出现Error: Entrypoint is not a Dart file

Flutter在Android studio运行出现Error: Entrypoint is not a Dart file

NE综合实验2:RIP 与 OSPF 动态路由精细配置及ACL访问控制列表 电脑

NE综合实验2&#xff1a;RIP 与 OSPF 动态路由精细配置及ACL访问控制列表 实验拓扑图实验需求 1.按照图示配置IP地址 2.按照图示区域划分配置对应的动态路由协议 3.在R7上配置dhcp服务器&#xff0c;能够让pc可以获取IP地址 4.将所有环回⼝宣告进ospf中&#xff0c;将环回⼝7宣…

Kafka 控制器(Controller)详解:架构、原理与实战

目录Kafka 控制器&#xff08;Controller&#xff09;详解&#xff1a;架构、原理与实战一、控制器的核心职责1. 元数据管理2. 分区状态机3. 故障恢复4. 集群操作协调二、传统 ZooKeeper 模式下的控制器1. 控制器选举机制2. 控制器与 ZooKeeper 的交互3. 潜在问题三、KRaft 模式…

【C++基础】#define vs constexpr:C++ 编译期常量的双雄对决(面试高频考点 + 真题解析)

​在 C++ 面试中,#define与constexpr的对比堪称 “元老级” 考点 —— 据统计,在 2023-2024 年的 C++ 工程师面试中,该知识点的出现频率高达 72%,尤其是在字节跳动、腾讯、华为等企业的校招 / 社招中,几乎是必问内容。​ 这两个语法元素都与 “编译期常量” 相关,但背后却…

k8s环境使用Operator部署Seaweedfs集群(上)

作者&#xff1a;闫乾苓 文章目录前言4.1 前置条件4.2 部署seaweedfs-operator4.3 准备operator镜像4.4 使用operator部署Seaweedfs集群4.4.1 部署StorageClass4.4.2 使用StorageClass预先创建PV前言 SeaweedFS Operator是一个Kubernetes Operator&#xff0c;用于自动化部署和…

Git CLI高危任意文件写入漏洞(CVE-2025-48384)PoC已公开

Git CLI&#xff08;命令行界面&#xff09;中存在一个高危漏洞&#xff0c;攻击者可利用该漏洞在Linux和macOS系统上实现任意文件写入。目前该漏洞的概念验证&#xff08;PoC&#xff09;利用代码已公开。该漏洞编号为CVE-2025-48384&#xff0c;CVSS严重性评分为8.1分&#x…

前端开发中关于表单内容的使用和基础知识

在前边&#xff0c;我们已经写过Web前端开发&#xff0c;Web前端开发&#xff0c;万字详细博文带你HTML&#xff0c;CSS快速入门&#xff08;上篇&#xff09;和Web前端开发&#xff0c;一文带你HTML&#xff0c;CSS快速入门&#xff08;下篇&#xff09;&#xff0c;使用近两万…

linux 安装mysql保姆教程

安装包下载地址: MySQL :: Download MySQL Community Server (Archived Versions) 解压到安装包&#xff1a; tar -zxvf mysql-5.7.36-linux-glibc2.12-x86_64.tar.gz 创建Mysql用户组和用户 groupadd mysql useradd -r -g mysql mysql 编译安装并初始化 进入/home/mysql/m…

Android系统的问题分析笔记 - Android上的调试方式 bugreport

在Android开发和系统调试中&#xff0c;bugreport&#xff08;错误报告&#xff09; 是一份包含设备详细系统状态、运行日志及应用行为的综合报告&#xff0c;是定位和诊断App崩溃、系统异常、性能问题等的核心工具。无论是开发者排查用户反馈的问题&#xff0c;还是设备厂商调…

GESP2025年6月认证C++四级( 第三部分编程题(2)排序)

参考程序&#xff1a;#include <cstdio> #include <algorithm> #include <vector> #include <iostream> using namespace std;int main() {int n, ans 0;// 读取学生人数scanf("%d", &n);// 用 vector 存储每个学生的身高和体重&#x…

SQL155 大小写混乱时的筛选统计

SQL155 大小写混乱时的筛选统计 题目理解 假设我们有一个考试系统数据库&#xff0c;里面有&#xff1a; exam_record表&#xff1a;记录学生考试作答情况examination_info表&#xff1a;记录考试信息&#xff0c;包括每个考试的类别标签(tag) ​问题描述​&#xff1a; 有…

无人机图像中的小目标检测新利器:深入解析 LAM-YOLO 模型

【导读】 随着无人机技术的发展&#xff0c;从交通监控到农业测绘&#xff0c;各类任务中对“空中视角下的小目标检测”需求激增。然而&#xff0c;由于无人机拍摄视角多变、目标尺寸微小、环境光照复杂等因素&#xff0c;传统检测模型常常出现“漏检”“误检”问题。 LAM-YO…

Rust 基础大纲

Rust 基础大纲1.Summary安装教材2 Rust 源1.Summary 安装 https://www.rust-lang.org/zh-CN/tools/install curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh# 安装完成后&#xff0c;验证是否成功 rustc -V cargo -V# 创建项目 cargo new my_project # 编译项…

PostgreSQL 大数据量(超过50GB)导出方案

1.正常导出导出指定库./pg_dump -d test_db -p 2360 > /home/softwares/postgresql/test_db.sql导出指定表./pg_dump -p 2360 -U postgres -t test_schema.test_table test_db > /home/softwares/postgresql/m.sql-t参数说明&#xff0c;-t test_schema.test_table test…