当前位置: 首页 > news >正文

0126_状态模式(State)

状态模式(State)

意图

允许对象在内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

UML 图

State

优点

  1. 行为与状态绑定:将特定状态下的行为局部化到对应的状态类中
  2. 消除条件判断:避免了大量的if-else状态判断逻辑
  3. 状态转换明确:使状态转换流程更加清晰和可管理
  4. 易于扩展:新增日常状态不需要修改现有代码
  5. 职责分离:每个状态类只关注自己的行为,符合单一职责原则

缺点

  1. 类数量增加:每个日常状态都需要一个具体的状态类
  2. 状态转换逻辑:状态转换可能需要在多个类中维护
  3. 上下文依赖:状态类需要了解上下文信息
  4. 初始化复杂:对于简单的状态机可能显得过于复杂
  5. 性能考虑:频繁的状态切换可能带来性能开销

代码示例

以人类一天的不同状态(睡眠-->起床-->吃饭-->运动-->睡眠)为例:

1. 状态接口 (State Interface)

// 日常状态接口
public interface DailyState {void handle(Person person);String getStateName();void performAction();
}

2. 上下文 (Context) - 人类

// 上下文 - 人类
public class Person {private DailyState currentState;private String name;private int energyLevel; // 能量级别public Person(String name) {this.name = name;this.energyLevel = 100; // 初始能量满格this.currentState = new SleepingState(); // 默认睡眠状态}public void setState(DailyState state) {this.currentState = state;System.out.println("🌞 " + name + " 进入状态: " + state.getStateName());}public void performCurrentAction() {System.out.print("👤 " + name + " ");currentState.performAction();}public void handleDailyRoutine() {currentState.handle(this);}public void consumeEnergy(int amount) {energyLevel -= amount;System.out.println("⚡ 能量消耗: " + amount + ", 剩余能量: " + energyLevel);}public void restoreEnergy(int amount) {energyLevel += amount;if (energyLevel > 100) energyLevel = 100;System.out.println("🔋 能量恢复: " + amount + ", 当前能量: " + energyLevel);}public int getEnergyLevel() {return energyLevel;}public String getName() {return name;}public DailyState getCurrentState() {return currentState;}// 开始新的一天public void startDay() {System.out.println("\n=== " + name + " 开始新的一天 ===");handleDailyRoutine();}
}

3. 具体状态 (Concrete States)

// 睡眠状态
public class SleepingState implements DailyState {@Overridepublic void handle(Person person) {if (person.getEnergyLevel() < 30) {System.out.println("😴 " + person.getName() + " 能量不足,需要睡觉恢复");person.restoreEnergy(70);// 睡醒后转换为起床状态person.setState(new WakingUpState());} else {System.out.println("⏰ " + person.getName() + " 已经休息够了,该起床了");person.setState(new WakingUpState());}}@Overridepublic String getStateName() {return "睡眠中";}@Overridepublic void performAction() {System.out.println("正在睡觉... 💤");}
}// 起床状态
public class WakingUpState implements DailyState {@Overridepublic void handle(Person person) {System.out.println("☀️ " + person.getName() + " 醒来,开始新的一天");person.consumeEnergy(10); // 起床消耗能量// 起床后需要吃饭person.setState(new EatingState());}@Overridepublic String getStateName() {return "起床中";}@Overridepublic void performAction() {System.out.println("正在起床,伸个懒腰... 🛏️");}
}// 吃饭状态
public class EatingState implements DailyState {@Overridepublic void handle(Person person) {System.out.println("🍽️ " + person.getName() + " 开始用餐");person.restoreEnergy(40); // 吃饭恢复能量person.consumeEnergy(5);  // 吃饭也消耗少量能量// 根据能量水平决定下一个状态if (person.getEnergyLevel() > 80) {System.out.println("👍 " + person.getName() + " 能量充足,可以开始活动");// 这里可以转换为工作或活动状态person.setState(new SleepingState()); // 简化示例,回到睡眠} else {System.out.println("😴 " + person.getName() + " 还需要休息");person.setState(new SleepingState());}}@Overridepublic String getStateName() {return "用餐中";}@Overridepublic void performAction() {System.out.println("正在享受美食... 🍎");}
}// 活动状态(扩展示例)
public class ActivityState implements DailyState {@Overridepublic void handle(Person person) {System.out.println("🏃 " + person.getName() + " 开始活动");person.consumeEnergy(30);if (person.getEnergyLevel() < 40) {System.out.println("🍽️ " + person.getName() + " 能量低,需要吃饭");person.setState(new EatingState());} else if (person.getEnergyLevel() < 20) {System.out.println("😴 " + person.getName() + " 太累了,需要睡觉");person.setState(new SleepingState());}}@Overridepublic String getStateName() {return "活动中";}@Overridepublic void performAction() {System.out.println("正在进行日常活动... 🏋️");}
}

4. 状态转换管理器

// 日常状态管理器
public class DailyStateManager {public static void simulateDay(Person person) {System.out.println("\n📅 模拟 " + person.getName() + " 的一天");// 初始状态:睡眠person.setState(new SleepingState());person.performCurrentAction();person.handleDailyRoutine();// 起床person.performCurrentAction();person.handleDailyRoutine();// 吃饭person.performCurrentAction();person.handleDailyRoutine();// 再次睡眠,完成一天循环person.performCurrentAction();person.handleDailyRoutine();System.out.println("🌙 " + person.getName() + " 的一天结束了");}public static void simulateMultipleDays(Person person, int days) {for (int i = 1; i <= days; i++) {System.out.println("\n========== 第 " + i + " 天 ==========");simulateDay(person);}}
}

5. 客户端代码

public class StatePatternDemo {public static void main(String[] args) {// 创建人类对象Person person = new Person("小明");System.out.println("=== 个人状态模拟 ===");System.out.println("初始能量: " + person.getEnergyLevel());// 模拟一天的生活DailyStateManager.simulateDay(person);System.out.println("\n=== 多天模拟 ===");Person anotherPerson = new Person("小红");DailyStateManager.simulateMultipleDays(anotherPerson, 3);System.out.println("\n=== 手动状态控制 ===");Person manualPerson = new Person("手动控制者");// 手动设置状态manualPerson.setState(new SleepingState());manualPerson.performCurrentAction();manualPerson.handleDailyRoutine();manualPerson.setState(new WakingUpState());manualPerson.performCurrentAction();manualPerson.handleDailyRoutine();manualPerson.setState(new EatingState());manualPerson.performCurrentAction();manualPerson.handleDailyRoutine();System.out.println("最终能量: " + manualPerson.getEnergyLevel());}
}

在Java标准库中的应用

状态模式在Java标准库中的类似应用:

  1. 生命周期管理
// Servlet 生命周期状态管理
public interface Servlet {void init(ServletConfig config);    // 初始化状态void service(...);                 // 运行状态void destroy();                    // 销毁状态
}
  1. 线程状态管理
// Thread 状态枚举
Thread thread = new Thread();
Thread.State state = thread.getState();
// 状态包括: NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED
  1. 工作流状态
// 各种工作流框架中的状态管理
// 如订单状态:待支付、已支付、已发货、已完成等
  1. 游戏角色状态
// 游戏开发中的角色状态管理
// 如:站立、行走、奔跑、跳跃、攻击、受伤等状态

总结

状态模式通过将人类一天中的不同行为状态(起床、吃饭、睡觉)封装成独立的状态类,使得状态转换和行为变化更加清晰和易于管理。每个状态类只关注自己在特定状态下的行为,避免了复杂的条件判断逻辑。这种模式特别适合用于那些有明确状态转换流程的场景,如日常生活规律、工作流程、游戏状态管理等。通过状态模式,我们可以轻松地扩展新的日常状态(如工作、娱乐等),而不需要修改现有的状态管理逻辑。

http://www.wxhsa.cn/company.asp?id=1659

相关文章:

  • Visual Studio 2026 预览体验版现已发布,一起来看看带来哪些新功能!
  • 基于RK3568/RK3576/RK3588/全志H3/飞腾芯片/国产UOS等/国标GB28181监控系统
  • Go语言读写锁(RWMutex)底层原理详解
  • 【GitHub每日速递】无需提示词!Nano Bananary香蕉超市:AI绘画玩法多到停不下来
  • 小题狂练 (J)
  • Drift数据库开发实战:类型安全的SQLite解决方案
  • DELPHI FireDAC连接EXCEL文件
  • 读人形机器人09教育行业
  • PHP判断字符串是否包含中文
  • 当我们红尘作伴,活得潇潇洒洒
  • 诡异的mysql8的问题
  • 二叉树理论
  • 支付中心的熔断降级要怎么做
  • 协议版iM蓝号检测,批量筛选iMessages数据,无痕检测是否开启iMessage服务
  • 栈和队列总结
  • 工业互联网认知实训台-一句话介绍
  • 湾区杯 SilentMiner WP
  • Python-课后题题目-1.1编程世界初探
  • Python-课后题题目-1.2初识python语言
  • node和npm相关的记录
  • 在Spring boot 中使用@master 设置主从数据库
  • 设计模式-装饰器模式 - MaC
  • 【API接口】最新可用河马短剧接口
  • 第 16 章反射(reflection)
  • 自我介绍+软工5问
  • 电容器+动生电动势+自由落体模型
  • 引用(reference)
  • 设计模式-组合模式 - MaC
  • 【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态
  • tmux 使用教程