BLoC vs Riverpod:命令式系统 与 声明式系统的两条架构路线

很多人把 BLoC 和 Riverpod 当成“两个 Flutter 状态管理框架”来选。
但当项目复杂到一定程度,你会发现:

👉 这根本不是“库选型问题”,而是系统建模路线选择问题

更准确地说:
BLoC 和 Riverpod,代表了两种非常典型的系统设计思想:
命令式系统 vs 声明式系统。

一、先跳出 Flutter:什么是“命令式 vs 声明式”

在软件工程中,一个非常经典的区分是:

  • 命令式(Imperative):我告诉系统“发生了什么、要做什么”

  • 声明式(Declarative):我告诉系统“关系是什么、结果应当是什么”

🌱 命令式系统关心的是:

  • 发生了什么?
  • 系统该执行什么动作?
  • 状态如何一步步演进?

🌱 声明式系统关心的是:

  • 谁由谁决定?
  • 这个结果依赖哪些输入?
  • 当输入变化,结果自然该变化

UI 世界里我们熟悉的是:

  • 命令式 UI:手动操作 View
  • 声明式 UI:描述 UI 结构

但在状态管理和架构层面,同样存在这两条路线。

二、Riverpod:典型的“声明式系统”

Riverpod 的核心不是“事件”,而是:

👉依赖关系

final totalPriceProvider = Provider((ref) { final items = ref.watch(cartProvider); final coupon = ref.watch(couponProvider); return calc(items, coupon); });

你在这里没有说“什么时候更新 totalPrice”,
你只是声明了一个关系

totalPrice = f(items, coupon)

剩下的事情全部交给系统:

  • items 变 → totalPrice 自动变
  • coupon 变 → totalPrice 自动变
  • 没人用 → 可以回收
  • 上游替换 → 下游自动重建

👉 这是一个声明式依赖系统

你描述的是:

“这个东西由这些东西决定。”

而不是:

“当这个变了你要去改那个。”

Riverpod 的系统风格

  • 变化来自:上游节点变化

  • 系统核心:依赖图

  • 程序员角色:声明关系

  • 系统角色:负责传播

非常像:

  • Excel 公式系统

  • React / Compose 状态派生

  • DI 容器 + 响应式引擎

👉 这是声明式路线

三、BLoC:典型的“命令式系统”

BLoC 的核心不是“谁依赖谁”,而是:

👉发生了什么

bloc.add(SubmitOrder()); bloc.add(Refresh()); bloc.add(DeviceDisconnected());

系统的所有变化,都必须通过:

👉事件(Event)

Bloc 做的事情是:

(当前状态, 收到事件) -> 新状态

你必须显式写清楚:

  • 有哪些事件
  • 有哪些状态
  • 每个状态下收到某事件会发生什么

👉 这是一个事件驱动状态机

你描述的是:

“系统经历了什么,它因此走到了哪一步。”

而不是:

“这个值由谁算出来。”

BLoC 的系统风格

  • 变化来自:显式事件
  • 系统核心:状态机
  • 程序员角色:设计流程
  • 系统角色:执行迁移

非常像:

  • Redux / MVI
  • 协议状态机
  • 工作流引擎
  • 后端事件驱动系统

👉 这是命令式路线

四、把差别说透:不是“写法”,是“控制权”

真正的差别在于:

👉系统变化由谁主导。

Riverpod:

数据变了 → 系统自动推导后果

你交给系统的是“关系”,
系统掌控的是“变化传播”。

BLoC:

发生了什么 → 系统执行对应行为

你交给系统的是“事件”,
你自己掌控的是“演进规则”。

这正是命令式 vs 声明式在系统层面的体现。

五、选型不是二选一,而是“你在解决什么问题”

更偏 Riverpod 的场景

  • 派生状态多
  • 数据联动强
  • 依赖复杂
  • 生命周期复杂
  • 资源型系统(repo / cache / service)

👉 本质是结构问题


更偏 BLoC 的场景

  • 状态阶段多
  • 流程复杂
  • 异常分支多
  • 行为必须可推理
  • 协议 / 设备 / 业务流

👉 本质是行为问题

六、成熟架构里最常见的组合

现实项目里,最常见、最稳的结构往往是:

Riverpod —— 管系统结构 / 资源 / 依赖 BLoC —— 管业务流程 / 页面行为 / 状态机

也就是:

👉 Riverpod 解决“系统怎么连起来”
👉 BLoC 解决“系统怎么走下去”

七、把这条认知线拉回你最初的直觉

你说:

它们有点像命令式 UI 和声明式 UI

这个直觉是完全正确的,只是层级更高:

👉 不是 UI 写法层
👉 是系统建模层

你感受到的,其实是:

👉控制权从“人”交给“系统” vs 从“系统”交回“人”

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

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

相关文章

IT6508:4通道DisplayPort1.2转双总线TTL转换器

IT6508 是一款高性能单芯片 DisplayPort 转 TTL 输出转换器。内置的DisplayPort接收器完全兼容DisplayPort 1.2a和HDCP 1.3/2.3规范。采用4通道HBR2(高比特率2)配置时,DP接收机可支持最高VESA分辨率至WUXGA(1920 x 1200120 Hz&…

Nodejs和vue框架的基于.的社区服务平台__没 项目源码

文章目录社区服务平台项目摘要--nodejs技术栈--结论源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!社区服务平台项目摘要 该项目基于Node.js后端与Vue.js前端构建,旨在为社区居民提供信息交互、资源共享及活动组织的数字化…

我用 Gemini 3 Pro 手搓了一个并发邮件群发神器(附源码)

这个周末我失业了 。起因很简单:公司项目原因,我需要给订阅列表里的几千个用户发一封更新通知。 市面上的邮件营销工具(Mailchimp之类)死贵,还要一个个导入联系人;自己写脚本吧,以前得折腾半天 …

IT6251FN:LVDS转DisplayPort 1.1a发射机

IT6251 是一款高性能单芯片 De-SSC LVDS 转 DisplayPort 转换器。结合LVDS接收器和DisplayPort发射器,IT6251通过转换功能支持LVDS输入和DisplayPort 1.1a输出。内置的LVDS接收器支持单链路和双链路LVDS输入,内置的DisplayPort发射器完全符合DisplayPort…

Nodejs和vue框架的基于大数据的水产品安全信息管理系统_ 可视化大屏系统

文章目录基于大数据的水产品安全信息管理系统可视化大屏摘要--nodejs技术栈--结论源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!基于大数据的水产品安全信息管理系统可视化大屏摘要 该系统结合Node.js后端与Vue.js前端框架&#xff0…

Agent Skills解决了什么问题?何时使用?

Agent Skills 可以被看作是给 AI 助手配备的“职业技能培训手册”。简单来说,它的核心目标是让 AI 从一个“通才”变成“身怀绝技的专家”,并且在处理复杂任务时更加稳定、高效。🎯 Agent Skills 到底解决了什么问题?在 Agent Ski…

性能监控之首屏性能监控小实践

背景:终于完成了阶段性的首屏性能优化的开发部分,该写监控代码验收成效了,这两天研究了下,先看下结果吧:核心性能指标均实现大幅下降,优化效果显著,具体分析如下:指标优化前均值&…

cesium 优化面

节点优化提升加载面数据 // 简化边界数据 function simplifyPolygon(positions, tolerance) {// 实现简化算法或使用第三方库return simplifiedPositions; }// 使用Primitive API(更节省内存) function createOptimizedPolygon(positions) {const geome…

JavaScript Date 语法要过时了!以后用这个替代!

1. 前言作为一名前端开发工程师,你一定被 JavaScript 的日期处理折磨过。这不是你的问题,是 JavaScript 自己的问题——它的 Date 功能真的很糟糕。2. Date 的离谱行为让我给你举几个例子,你就明白有多离谱了:月份从 0 开始计数&a…

Nodejs和vue框架的基于的家庭设备维修服务系统__没 项目源码

文章目录项目概述核心功能模块技术实现亮点部署与扩展性--nodejs技术栈--结论源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!项目概述 基于Node.js和Vue框架的家庭设备维修服务系统是一个全栈Web应用,旨在为用户提供便捷的…

产品催: 1 天优化 Vue 官网 SEO?我用这个插件半天搞定(不重构 Nuxt)

上周四早上刚坐下,还没来得及摸鱼,产品就紧急拉了个会,说为了搞流量,咱们官网得做 SEO 优化。 然后直接甩了一份市场部出的 SEO 规范文档到群里:这文档里的要求:每个页面要有独立标题、关键词,内…

Nodejs和vue框架的个人健康菜谱生成系统_ 项目源码

文章目录项目概述技术架构核心功能算法逻辑代码结构部署与扩展--nodejs技术栈--结论源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!项目概述 该项目基于Node.js与Vue.js构建了一个智能化的个人健康菜谱生成系统。后端采用Node.js的Exp…

常用的sql语句汇总(个人版)

1、sql按照指定数组顺序查询数据 2、数据库SQL 某字段按首字母排序 基础语句 1、SELECT:选择数据表中的数据 SELECT column_name1, column_name2 FROM table_name;2、WHERE:筛选符合条件的数据 SELECT column_name FROM table_name WHERE column_nam…

前端面试了10来个人,聊聊他们被挂的原因..

现在前端面试真的头大!这周面了9个人全挂,不是没经验,是细节准备太拉胯了! 1. JS基础不牢:闭包、事件循环这些核心概念说不明白,手写Promise.all、深拷贝还卡壳。得搞懂V8引擎咋干活,this绑定、…

AI人脸隐私卫士效果对比:传统打码与智能打码的差异

AI人脸隐私卫士效果对比:传统打码与智能打码的差异 1. 引言:为何需要更智能的人脸隐私保护? 随着社交媒体、公共监控和数字档案的普及,个人面部信息正以前所未有的速度被采集和传播。传统的“手动打码”方式虽然简单直接&#x…

【豆包写的】深入解析 torch.argmax 中 dim=1 与 one-hot 转整数标签的关系

深入解析 torch.argmax 中 dim1 与 one-hot 转整数标签的关系 你想理解在 torch.argmax(y_true_cce, dim1) 中参数 dim1 的具体含义,尤其是结合把 one-hot 标签转换为整数标签的场景——这是 PyTorch 处理张量维度的核心基础,我会用通俗的语言可视化的例…

基于超像素(super-pixel)边缘检测的呼吸监测和小波去噪、EVM PVM进行对比实验附Matlab复现

✅作者简介:热爱科研的Matlab仿真开发者,擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。 🍎 往期回顾关注个人主页:Matlab科研工作室 👇 关注我领取海量matlab电子书和数学建模资料 &#x1…

论文写作“隐藏技巧”:7款AI神器告别焦虑,导师不会告诉你的秘密

你知道吗?你隔壁实验室那个从不熬夜、却能轻松产出高质量论文的同学,可能正在用这些“隐藏工具”。而你的导师,大概率知道,却永远不会主动告诉你。 是不是经常感觉,论文写作像一场信息不对等的“军备竞赛”&#xff1f…

数据库常用的SQL查询语句(非常详细),看完这一篇就足够了

1. 无条件查询 --查询表中所有数据 select * from 表名;2. 查询在…到…之间(between and / && / and) --查询users表中年龄在18~25岁之间的记录 --方式1 between..and.. select * from users where age between 18 and 25;--方式2 && select * from users w…

Debug:mlx-omni-server服务器用qwen3模型出错

背景:AI回答出错,开始以为是代码问题使得之前的对话出现在上下文,没想到是mlx-omni-server的问题 debug过程: 最开始比较好运地在github论坛找到同样的问题,大概率确认服务器出错。 之后用copilot写了一个简单的go代码…