订单状态流转/播放器控制/游戏角色行为…一个模式搞定所有状态驱动型逻辑!


经典场景:订单状态管理

假设你在开发一个外卖App,订单有以下状态:

  • 等待接单
  • 已接单
  • 配送中
  • 已完成
  • 已取消

每个状态下:

  • 显示的UI不同
  • 可执行的操作不同
  • 状态转换规则不同

传统实现方式(switch-case地狱):

class Order {String state = 'waiting'; // 状态字段Widget buildUI() {switch(state) {case 'waiting':return _buildWaitingUI();case 'accepted':return _buildAcceptedUI();// ...其他状态}}void performAction(String action) {switch(state) {case 'waiting':if (action == 'accept') {state = 'accepted';// 执行接单逻辑}break;case 'accepted':if (action == 'pickup') {state = 'delivering';// 执行取货逻辑}break;// ...其他状态}}
}

痛点:

  • 代码臃肿,一个类包含所有状态的逻辑
  • 添加新状态需要修改现有类
  • 状态转换逻辑分散在各处
  • 违反开闭原则(对扩展开放,对修改关闭)

状态模式解决方案

核心思想: 允许对象在其内部状态改变时改变它的行为,对象看起来像是修改了它的类。

三个关键角色:

  1. 上下文(Context): 维护当前状态,定义状态接口
  2. 抽象状态(State): 定义状态接口
  3. 具体状态(ConcreteState): 实现特定状态的行为

Flutter订单状态模式实现

1. 定义状态接口
abstract class OrderState {Widget buildUI(OrderContext context);void acceptOrder(OrderContext context);void pickUp(OrderContext context);void deliver(OrderContext context);void complete(OrderContext context);void cancel(OrderContext context);
}
2. 实现具体状态类
// 等待接单状态
class WaitingState implements OrderState {Widget buildUI(OrderContext context) {return Column(children: [Text('等待商家接单...', style: TextStyle(color: Colors.orange)),ElevatedButton(onPressed: () => context.acceptOrder(),child: Text('接单'),)],);}void acceptOrder(OrderContext context) {print('订单已接单');context.changeState(AcceptedState());}// 其他方法在当前状态下不适用void pickUp(OrderContext context) => _showError('接单后才能取货');void deliver(OrderContext context) => _showError('请先取货');void complete(OrderContext context) => _showError('订单未完成');void cancel(OrderContext context) {print('订单已取消');context.changeState(CanceledState());}void _showError(String msg) => print('操作失败: $msg');
}// 已接单状态
class AcceptedState implements OrderState {Widget buildUI(OrderContext context) {return Column(children: [Text('商家已接单', style: TextStyle(color: Colors.green)),ElevatedButton(onPressed: () => context.pickUp(),child: Text('取货'),)],);}void pickUp(OrderContext context) {print('商品已取货');context.changeState(DeliveringState());}// ...其他方法实现类似
}// 其他状态类:DeliveringState, CompletedState, CanceledState
3. 创建上下文类
class OrderContext {OrderState _state = WaitingState();void changeState(OrderState newState) {_state = newState;}// 委托所有操作给当前状态Widget buildUI() => _state.buildUI(this);void acceptOrder() => _state.acceptOrder(this);void pickUp() => _state.pickUp(this);void deliver() => _state.deliver(this);void complete() => _state.complete(this);void cancel() => _state.cancel(this);
}
4. 在Flutter组件中使用
class OrderScreen extends StatefulWidget {_OrderScreenState createState() => _OrderScreenState();
}class _OrderScreenState extends State<OrderScreen> {final OrderContext orderContext = OrderContext();Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('订单详情')),body: Center(child: orderContext.buildUI(),),floatingActionButton: FloatingActionButton(onPressed: () => orderContext.cancel(),tooltip: '取消订单',child: Icon(Icons.cancel),),);}
}

Flutter中的实际应用场景

场景1:媒体播放器控制
// 状态接口
abstract class PlayerState {void play(PlayerContext context);void pause(PlayerContext context);void stop(PlayerContext context);IconData get icon;
}// 具体状态
class PlayingState implements PlayerState { void play(PlayerContext context) => print('已在播放中'); void pause(PlayerContext context) => context.changeState(PausedState()); void stop(PlayerContext context) => context.changeState(StoppedState()); IconData get icon => Icons.pause;
}class PausedState implements PlayerState { void play(PlayerContext context) => context.changeState(PlayingState()); void pause(PlayerContext context) => print('已暂停'); void stop(PlayerContext context) => context.changeState(StoppedState()); IconData get icon => Icons.play_arrow;
}// 上下文
class PlayerContext {PlayerState _state = StoppedState();void changeState(PlayerState state) => _state = state;IconData get icon => _state.icon;void play() => _state.play(this);void pause() => _state.pause(this);void stop() => _state.stop(this);
}// 在UI中使用
IconButton(icon: Icon(playerContext.icon),onPressed: () {setState(() {if (playerContext is PlayingState) {playerContext.pause();} else {playerContext.play();}});},
)
场景2:游戏角色状态
// 游戏角色状态
abstract class CharacterState {void move();void attack();void takeDamage();String get animation;
}// 具体状态
class IdleState implements CharacterState { void move() => print('开始移动'); void attack() => print('发起攻击'); void takeDamage() => print('受到伤害'); String get animation => 'idle_anim';
}class WalkingState implements CharacterState { void move() => print('继续移动'); void attack() => print('移动中攻击'); void takeDamage() => print('移动中受伤'); String get animation => 'walk_anim';
}// 上下文
class GameCharacter {CharacterState _state = IdleState();void changeState(CharacterState state) => _state = state;void update() {// 游戏循环中更新状态render(_state.animation);}void onMoveCommand() => _state.move();void onAttackCommand() => _state.attack();void onDamage() => _state.takeDamage();
}
场景3:表单验证状态
abstract class FormState {bool validate();void submit();Color get buttonColor;
}class InvalidState implements FormState { bool validate() => false; void submit() => print('表单无效,不能提交'); Color get buttonColor => Colors.grey;
}class ValidState implements FormState { bool validate() => true; void submit() => print('提交表单'); Color get buttonColor => Colors.blue;
}class FormContext {FormState _state = InvalidState();void validateForm(List<String> errors) {_state = errors.isEmpty ? ValidState() : InvalidState();}void submit() => _state.submit();Color get buttonColor => _state.buttonColor;
}

状态模式与Flutter状态管理的结合

将状态模式与Provider结合使用:

// 创建状态提供者
class OrderStateProvider extends ChangeNotifier {OrderContext _orderContext = OrderContext();OrderContext get orderContext => _orderContext;void acceptOrder() {_orderContext.acceptOrder();notifyListeners();}void pickUp() {_orderContext.pickUp();notifyListeners();}// 其他操作...
}// 在顶层注册
void main() {runApp(ChangeNotifierProvider(create: (context) => OrderStateProvider(),child: MyApp(),),);
}// 在组件中使用
Consumer<OrderStateProvider>(builder: (context, provider, child) {return provider.orderContext.buildUI();}
)// 执行操作
context.read<OrderStateProvider>().acceptOrder();

状态模式最佳实践

  1. 何时使用状态模式:

    • 对象的行为取决于它的状态
    • 状态数量较多(>3)
    • 状态转换逻辑复杂
    • 需要避免使用大量的条件语句
  2. Flutter特化技巧:

    // 使用枚举定义状态类型
    enum OrderStateType { waiting, accepted, delivering, completed, canceled }// 状态工厂
    OrderState createState(OrderStateType type) {switch(type) {case OrderStateType.waiting: return WaitingState();case OrderStateType.accepted: return AcceptedState();// ...}
    }// 在上下文中保存状态类型
    class OrderContext {OrderStateType get stateType => // 从当前状态推断类型
    }
    
  3. 状态转换管理:

    // 状态转换表
    const Map<OrderStateType, Map<String, OrderStateType>> transitions = {OrderStateType.waiting: {'accept': OrderStateType.accepted,'cancel': OrderStateType.canceled,},OrderStateType.accepted: {'pickup': OrderStateType.delivering,'cancel': OrderStateType.canceled,},// ...
    };// 在上下文中使用
    void transition(String action) {final nextStateType = transitions[stateType]?[action];if (nextStateType != null) {changeState(createState(nextStateType));}
    }
    
  4. 状态持久化:

    // 保存状态到本地
    void saveState() {SharedPreferences.getInstance().then((prefs) {prefs.setString('order_state', _stateType.toString());});
    }// 恢复状态
    void restoreState() {SharedPreferences.getInstance().then((prefs) {final stateStr = prefs.getString('order_state');if (stateStr != null) {final stateType = OrderStateType.values.firstWhere((e) => e.toString() == stateStr);changeState(createState(stateType));}});
    }
    

状态模式 vs 策略模式

特性状态模式策略模式
目的管理状态转换和状态相关行为封装可互换的算法
状态知晓状态知道其他状态策略相互独立
状态改变状态可改变上下文的状态策略通常不改变上下文
典型应用订单状态、播放器控制支付策略、排序算法

状态模式的高级变体

1. 分层状态机
// 基础状态
abstract class BaseState {void handleEvent(Event event);
}// 具体状态可以包含子状态
class DeliveryState implements BaseState {BaseState _currentSubState = PreparingState();void handleEvent(Event event) {_currentSubState.handleEvent(event);// 处理状态转换if (event is PreparedEvent) {_currentSubState = OnTheWayState();}}
}// 子状态
class PreparingState implements BaseState {void handleEvent(Event event) {if (event is PrepareCommand) {// 处理准备命令}}
}
2. 历史状态
class OrderContext {final List<OrderState> _stateHistory = [];OrderState _currentState = WaitingState();void changeState(OrderState newState) {_stateHistory.add(_currentState);_currentState = newState;}void undo() {if (_stateHistory.isNotEmpty) {_currentState = _stateHistory.removeLast();}}
}

总结:状态模式是你的行为变身器

  • 核心价值: 将不同状态的行为局部化到各自类中
  • Flutter优势:
    • 消除庞大的条件语句
    • 简化状态转换逻辑
    • 符合单一职责原则
    • 提高代码可扩展性和可维护性
  • 适用场景: 订单系统、游戏角色、媒体播放器、工作流引擎、UI状态管理

🎮 设计启示: 当你的对象需要根据状态改变行为,且状态转换逻辑复杂时,状态模式是优雅的解决方案!

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

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

相关文章

数据库9:数据库字符编码调整与校队(排序)规则

一.常用字符编码 1.ASCII编码 用一个字节表示一个字符 2.ANSI编码 每个国家为了显示本国的语言而对ASCII码进行了拓展 用两个字节表示一个汉字&#xff0c;中国的ANSI编码是GB2312编码&#xff08;简体&#xff09;&#xff0c;日本的ANSI编码是JIS编码&#xff0c;台湾的A…

人脸活体识别4:Android实现人脸眨眼 张嘴 点头 摇头识别(可实时检测)

人脸活体识别4&#xff1a;Android实现人脸眨眼 张嘴 点头 摇头识别(可实时检测) 目录 人脸活体识别4&#xff1a;Android实现人脸眨眼 张嘴 点头 摇头识别(可实时检测) 1. 前言 2.人脸活体识别方法 &#xff08;1&#xff09;基于人脸动作的检测​​ &#xff08;2&…

DAY1-Linux操作系统1

文章参考【黑马程序员Python教程_600集Python从入门到精通教程&#xff08;懂中文就能学会&#xff09;】 https://www.bilibili.com/video/BV1ex411x7Em/?p40&share_sourcecopy_web&vd_source263bbee2ddeb835c3ab6d9d3c80e0f7c 一.常用命令简单介绍 使用软件 虚拟机…

第十二节:Vben Admin 最新 v5.0 (vben5) + Python Flask 快速入门 - 两种权限控制方式(附前后端代码)

Vben5 系列文章目录 💻 基础篇 ✅ 第一节:Vben Admin 最新 v5.0 (vben5) + Python Flask 快速入门 ✅ 第二节:Vben Admin 最新 v5.0 (vben5) + Python Flask 快速入门 - Python Flask 后端开发详解(附源码) ✅ 第三节:Vben Admin 最新 v5.0 (vben5) + Python Flask 快速入…

华为云Flexus+DeepSeek征文 | 华为云 ModelArts Studio 赋能 AI 法务:合同审查与法律文件生成系统

一、引言 在法律行业数字化转型的浪潮中&#xff0c;AI 技术正重塑法律服务的流程与效率。本文介绍如何利用华为云 ModelArts Studio 构建一套完整的 AI 法务系统&#xff0c;实现合同审查、法律文件生成、法律咨询与风险识别的智能化解决方案。 二、系统架构设计 &#xff0…

SQL的底层逻辑解析

SQL的底层逻辑涉及数据库管理系统(DBMS)如何解析、优化和执行SQL查询&#xff0c;主要包括以下几个层面&#xff1a; ​查询处理流程​ 解析器(Parser)&#xff1a;将SQL语句转换为语法树查询优化器(Optimizer)&#xff1a;基于统计信息和成本模型生成最优执行计划执行引擎(Exe…

深入剖析AI大模型:PyTorch 技术详解

今天说一说PyTorch。作为一名python程序员&#xff0c;可能对它了解起来还是很快的。在人工智能浪潮席卷全球的当下&#xff0c;深度学习作为其核心技术&#xff0c;被广泛应用于图像识别、自然语言处理、语音识别等多个领域。而在深度学习的开发框架中&#xff0c;PyTorch 凭借…

物联网架构:定义、解释和实例

物联网&#xff08;IoT&#xff09;架构是一个复杂且多维度的概念&#xff0c;构成了物联网系统的核心框架。它是勾勒物联网设备、应用程序和技术如何相互交互以实现预期功能的蓝图。物联网架构并非 “一刀切” 的模型&#xff0c;而是会根据相关物联网系统的具体需求而有所不同…

拿到一台新服务器,怎么跑AI项目

公司新采购一台AI服务器&#xff0c;花大本钱装了个A6000显卡&#xff0c;今天来记录下新服务的使用步骤。 1、查看系统。 这台服务器预装了Ubuntu20.04系统。 lsb_release -a 查看下cpu、内存情况 top 看着还行。 再看下硬盘空间 df -h 空间不算小&#xff0c;2T。 2、…

IO--进程实操

1.创建一个进程扇 #include <051head.h> int main(int argc, const char *argv[]) {pid_t pid;for(int i0;i<4;i){pidfork();if(pid-1) //父进程{ERRLOG("fork error..\n");} else if(pid0) //这是子进程{ …

模型预测控制(MPC)概览

模型预测控制&#xff08;Model Predictive Control, MPC&#xff09; 一、理论基础与发展脉络 1. 历史起源 20世纪70年代起源于工业过程控制&#xff08;如化工领域的动态矩阵控制DMC、模型算法控制MAC&#xff09;&#xff0c;由Richalet、Mehra等学者提出&#xff0c;核心…

Python初体验:从入门到实践

Python无疑是开启编程世界大门的绝佳钥匙。今天,就让我们一起踏上Python的学习之旅。 #01 编写第一个Python程序 环境搭建好之后,上节已经编写了第一个Python程序。现在就好比,我们已经准备好了厨房和食材,要开始做第一道菜了。启动Jupyter后,在Jupyter中新建一个文件,…

【数字后端】- 什么是AOI、OAI cell?它们后面数字的含义

是什么&#xff1f; 不管是在DC综合阶段&#xff0c;还是在PR阶段&#xff0c;尝尝会出现OAI、AOI组合逻辑单元的身影。因为它们可以通过巧妙的串联和并联晶体管非常高效地实现组合逻辑&#xff0c;因此在VLSI设计中非常常用。但是它们也是高pin密度单元&#xff0c;也可能会造…

MQTTServer服务器根据MQTTClient客户端已订阅的主题推送 分发消息

网络读卡器介绍&#xff1a;https://item.taobao.com/item.htm?ftt&id22173428704&spma21dvs.23580594.0.0.52de2c1bgK3bgZ 本示例使用了MQTTNet插件 C# MQTTNETServer 源码 using MQTTnet.Client.Receiving; using MQTTnet.Server; using MQTTnet; using System; u…

【seismic unix 合并两个su文件】

Seismic Unix简介 Seismic Unix&#xff08;SU&#xff09;是由科罗拉多矿业学院开发的开源地震数据处理软件包&#xff0c;基于Unix/Linux环境运行。它提供了一系列命令行工具&#xff0c;用于地震数据加载、处理、分析和可视化&#xff0c;支持SEG-Y格式和SU自定义格式。SU广…

【vmware虚拟机使用】安装vmware workstations17

安装vmware17 本章学习目标VMware虚拟机简介开始实操下载VMware workstation虚拟机安装虚拟机配置虚拟机网络 总结 本章学习目标 1.安装vmware workstation虚拟机 2.自定义配置虚拟机网络&#xff0c;避免网络冲突 VMware虚拟机简介 ​ VMware的核心是Hypervisor&#xff0…

QT6 源(147)模型视图架构里的表格窗体 QTableWidget 的范例代码举例,以及其条目 QTableWidgetItem 类型的源代码。

&#xff08;1&#xff09;先用一个简单的例子&#xff0c;学习一下本类里的成员函数的使用。生成如下图的界面&#xff0c;表格窗体与初始数据&#xff1a; 查看其 ui_widget . h 文件 &#xff0c;里面的将是最标准的表格窗体的使用代码 &#xff1a; #ifndef UI_WIDGET_H #…

URL时间戳参数深度解析:缓存破坏与前端优化的前世今生

&#x1f50d; URL时间戳参数深度解析&#xff1a;缓存破坏与前端优化的前世今生 在日常的Web开发中&#xff0c;你是否注意到很多接口URL后面都会带有一个时间戳参数&#xff1f;比如 xxx/getMsg?_1751413509056。这个看似简单的参数背后&#xff0c;却隐藏着前端缓存策略、性…

分布式锁实现方式:基于Redis的分布式锁实现(Spring Boot + Redis)

Redis实现分布式锁的原理 Redis分布式锁基于其单线程执行命令的特性&#xff0c;通过原子操作实现多节点间的互斥访问。下面从原理、实现、问题及优化四个方面详细解析&#xff1a; 1.原子性与互斥性 Redis分布式锁的核心是原子性操作&#xff1a; 获取锁&#xff1a;使用SE…

linux升级降级内核实验

✅实验环境 vmware workstation 17 centos7.9 下载链接&#xff1a; https://vault.centos.org/7.9.2009/isos/x86_64/ ubuntu24.04 下载链接&#xff1a; https://old-releases.ubuntu.com/releases/24.04/ ✅实验目的 为了解决日常环境部署中某些驱动软件依赖特定内…