Repository 方法设计:suspend 与 Flow 的决选择指南(以朋友圈为例)

在Repo接口定义中,常见两类函数:

  • suspend functions:返回单一结果
  • 普通函数返回 Flow:返回一个结果流

这两类函数在 Room DAO 等库中都有体现。例如 observeUsers() 返回 Flow,因为它是一个观察者,每次表变化都会发射新的用户列表。


一、通用原则

  • 使用 suspend:当函数只产生一个结果时,例如数据库查询或调用外部服务
  • 使用 Flow:当函数可能产生未知数量的结果时,例如 WebSocket 连接或数据库观察

不推荐在只期望一个结果的场景使用 Flow,原因包括:

  1. 语义误导Flow 暗示多个结果
  2. 复杂度更高suspend 更简单、可读性更好、易于调试

二、朋友圈发送场景 ------ 使用 suspend

在发送朋友圈的业务中,很多操作都是一次性触发并返回结果,因此适合用 suspend

  • 发布朋友圈:用户点击"发送"后,等待结果返回
  • 删除朋友圈:一次性操作,执行后即结束
  • 点赞/取消点赞:触发后立即返回结果
  • 发表评论:提交后返回成功或失败

示例接口

三、朋友圈动态场景 ------ 使用 Flow

朋友圈的另一类需求是实时动态更新,例如:

  • 朋友圈列表:新内容发布后,列表需要自动刷新
  • 特定朋友圈详情:点赞数、评论数随时变化
  • 新朋友圈通知:好友发布新动态时推送
  • 互动更新:点赞、评论的实时变化

示例接口

四、 ViewModel与状态管理

ViewModel 的可观察状态通常用 StateFlow 表示。 因此,API 暴露 Flow 会更容易消费,可以直接用 stateIn 转换为 StateFlow

  • 小型应用:用 Flow 到处都行,差别不大
  • 复杂领域模型:滥用 Flow 会成为负担,suspend 更简洁
  • 最佳实践:可以定义辅助函数,把 suspend 转换为 StateFlow,避免强行用 Flow everywhere (不要为了迎合 ViewModel 的需要而让数据层所有 API 都返回 Flow,而是保持数据层 API 的简洁性(使用挂起函数),然后在 ViewModel 层通过辅助函数将一次性操作的结果转换为 StateFlow)。

五、决策流程图

我总结了一个图,如下:

六、总结原则

特征 suspend Flow
数据特性 静态,一次性 动态,持续变化
结果数量 单次结果 多个值序列
使用场景 发送朋友圈、删除、点赞、评论 列表更新、通知、互动变化
生命周期 执行完即结束 持续到取消收集

简单记忆

  • 操作像 动词 (做某事,例如"发送朋友圈") → 用 suspend
  • 操作像 名词 (观察某物,例如"朋友圈动态") → 用 Flow
相关推荐
不爱说话郭德纲6 小时前
告别漫长的HbuilderX云打包排队!uni-app x 安卓本地打包保姆级教程(附白屏、包体积过大排坑指南)
android·前端·uni-app
Sinclair11 小时前
简单几步,安卓手机秒变服务器,安装 CMS 程序
android·服务器
雮尘14 小时前
手把手带你玩转Android gRPC:一篇搞定原理、配置与客户端开发
android·前端·grpc
ktl15 小时前
Android 编译加速/优化 80%:一个文件搞定,零侵入零配置
android
alexhilton1 天前
使用FunctionGemma进行设备端函数调用
android·kotlin·android jetpack
冬奇Lab1 天前
InputManagerService:输入事件分发与ANR机制
android·源码阅读
张小潇1 天前
AOSP15 Input专题InputManager源码分析
android·操作系统
RdoZam1 天前
Android-封装基类Activity\Fragment,从0到1记录
android·kotlin
奥陌陌2 天前
android 打印函数调用堆栈
android
用户985120035832 天前
Compose Navigation 3 深度解析(二):基础用法
android·android jetpack