You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Bloc中使用Freezed库时应选择密封类还是构造函数实现方式?

Flutter Bloc 结合 Freezed 两种实现方案的场景对比与选型

方案1:密封类(联合类型)实现

这是Freezed最原生的密封类用法,把不同的状态拆成独立的子类,同一时间只会存在其中一个子类实例:

abstract class HomeState with _$HomeState {
  const factory HomeState.initial() = _Initial;
  const factory HomeState.addNewNoteButtonClicked(@Default(false)  bool isClicked) = AddNewNoteClicked;
  factory HomeState.addNewNote( Note value) = AddNewNote;
}

适用场景

  • 页面状态互斥:同一时间只会展示一种状态,比如加载中、加载成功、加载失败,三种状态不可能同时出现
  • 不同状态携带的参数差异大:比如initial状态不需要任何参数,addNewNote只需要传Note对象,不会产生冗余的无效字段,也避免了可空字段带来的空安全隐患
  • 状态分支处理逻辑复杂:需要在BlocBuilder/BlocListener中针对不同状态做完全独立的UI渲染或逻辑处理,Freezed自动生成的when/map方法可以强制要求覆盖所有状态分支,不会出现漏处理的情况

方案2:统一构造函数实现

本质是只声明一个状态类,所有状态变化都通过修改类的属性实现:

abstract class HomeState with _$HomeState {
  const factory HomeState({
    required Note value,
    required bool isClicked,
  }) = AddNewNoteClicked;
  factory HomeState.init() => HomeState(
        value: Note(value: ''),
        isClicked: false,
      );
}

适用场景

  • 状态属性可共存:多个状态属性不是互斥关系,可以同时生效,比如笔记编辑页同时需要存当前编辑的内容、按钮是否可点击、是否正在上传等多个并行的属性
  • 属性复用度高:所有属性都是页面全局需要用到的,不会出现某个状态下大量字段无意义的情况
  • 逻辑简单不需要多分支判断:UI不需要根据状态类型做完全不同的渲染,只是根据属性值调整局部UI,不需要写多分支判断逻辑,代码更简洁

选型判断规则

  • 优先判断状态是否互斥:如果状态之间是互斥关系,直接选密封类实现;如果多个属性可以同时生效,选统一构造实现
  • 看参数重合度:如果不同状态需要的参数重合度低于30%,选密封类避免冗余字段;如果所有属性都是全局通用,选统一构造
  • 看逻辑复杂度:如果需要针对不同状态做独立的跳转、弹窗、页面切换等逻辑,选密封类避免漏处理分支;如果只是局部UI调整,选统一构造更省事

内容的提问来源于stack exchange,提问作者Mariam Albarghouti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 18:57:03