从外包到甲方:一个老广程序员的 Flutter 状态管理实战与思考
去年十月,我还在天河软件园一家外包公司加班到凌晨两点,改着第 8 版需求文档里“微调一下 UI”的按钮颜色。那天广州下了场冷雨,我裹着那件穿了三年的优衣库羽绒服,站在珠江新城地铁站口,看着对面写字楼里还亮着的灯,心里只有一个念头:再这样下去,我怕是要在35岁前被优化掉。
那时我月薪15k,房租3500,老婆刚怀上二胎,压力山大。面试投了快两个月,终于在年底收到一家本地电商公司的终面通知——甲方,自研产品,Flutter 全栈开发岗。HR 电话里说:“我们最近在重构 App,状态管理这块有点混乱,你有实战经验吗?”
我嘴上答“有”,心里却慌得一批。因为在外包,我写的 Flutter 项目基本都是 setState 走天下,稍微复杂点就靠 Provider 硬扛,连 Riverpod 都没正经用过。更别提什么 BLoC、MobX、GetX 了——这些词我只在 GPT-4 生成的“Flutter 面试题 Top 20”里见过。
面试现场:被问懵的状态管理题
面试那天是周五下午,地点在越秀区一栋老式写字楼里,空调开得跟冰窖似的。技术负责人是个戴眼镜的中年大哥,上来就问:
“你们之前项目怎么处理状态共享?比如用户登录后,首页、购物车、个人中心都要同步更新。”
我硬着头皮说:“用 Provider,把用户信息放全局,然后 Consumer 监听变化。”
他点点头,又问:“如果某个页面依赖多个状态,比如商品列表要同时响应搜索关键词、分类筛选、网络加载状态,你怎么组织?”
我卡壳了。脑子里闪过一堆 if (loading) ... else if (error) ... else if (data != null) 的代码,但说不出系统性的方案。最后只能老实交代:“我们项目没那么复杂,一般拆成几个小 Provider,或者直接用 FutureBuilder。”
他笑了笑,没为难我,但补充了一句:“其实我们希望团队能统一状态管理规范,避免后期维护像‘意大利面条’。”
回家路上,我越想越焦虑。当晚翻出 GPT-4,让它模拟一场“高级 Flutter 开发面试”,重点问状态管理。结果它甩给我一串问题:
- Provider 和 Riverpod 本质区别是什么?
- BLoC 如何避免内存泄漏?
- 在大型项目中,如何选择合适的状态管理方案?
- 状态管理与架构设计(如 Clean Architecture)如何结合?
我盯着屏幕,手心冒汗。那一刻我意识到:外包三年,我缺的不是写代码的能力,而是系统性思维和工程规范意识。
入职后的真实战场:从混乱到有序
幸运的是,我还是拿到了 offer,月薪涨到22k。入职第一周,我就被分配到重构商品详情页的任务——这个页面当时用了三种状态管理方式:setState 控制 Tab 切换、Provider 管理购物车数量、FutureBuilder 加载商品数据。代码耦合严重,测试覆盖率几乎为零。
我和组里一个叫阿强的同事(地道潮汕人,但讲粤语比我溜)一起啃这块硬骨头。我们开了个会,决定统一用 Riverpod + AsyncNotifier 作为新标准。为什么选它?
- 编译安全:相比 Provider,Riverpod 不依赖
BuildContext,不会因为 widget 树变化导致监听失效。 - 组合性强:可以轻松组合多个 provider,比如
ref.watch(userProvider).whenData(...)。 - 测试友好:每个 notifier 可以独立单元测试,不用启动整个 widget 树。
举个具体例子:商品详情页需要同时获取商品信息、用户收藏状态、促销活动。以前是三个 FutureBuilder 嵌套,现在我们这样写:
final productDetailProvider = AsyncNotifierProvider.autoDispose<
ProductDetailNotifier, ProductDetail>(
ProductDetailNotifier.new,
);
class ProductDetailNotifier extends AsyncNotifier<ProductDetail> {
@override
Future<ProductDetail> build() async {
final productId = ref.watch(productIdProvider);
final user = await ref.watch(userProvider.future);
final product = await repository.fetchProduct(productId);
final isFavorite = await repository.checkFavorite(user.id, productId);
final promotions = await repository.getPromotions(productId);
return ProductDetail(
product: product,
isFavorite: isFavorite,
promotions: promotions,
);
}
}
在 UI 层,只需一行:
final detail = ref.watch(productDetailProvider);
return detail.when(
loading: () => LoadingView(),
error: (err, _) => ErrorView(err),
data: (data) => DetailView(data),
);
清晰、可测、可维护。 这就是甲方和外包最大的区别——他们愿意花时间做“正确的事”,而不是“快的事”。
我的 Flutter 状态管理最佳实践总结
经过半年实战,我总结出几点心得,分享给还在挣扎的兄弟们:
1. 小项目用 setState + Provider 足够
别一上来就搞 BLoC 或 GetX。如果只是个内部工具或 MVP 产品,过度设计反而拖慢进度。我之前外包项目很多就是这种,硬上架构反而让客户觉得“效率低”。
2. 中大型项目首选 Riverpod
它解决了 Provider 的痛点,又不像 BLoC 那样样板代码多。配合 AsyncNotifier,异步逻辑一目了然。而且社区生态成熟,GPT-4 也能给出靠谱示例(虽然别全信,但至少方向对)。
3. 状态要分层:UI 状态 vs 业务状态
- UI 状态(比如弹窗是否显示、Tab 选中项):放在 widget 自身或局部 provider。
- 业务状态(用户信息、订单数据):必须全局管理,且要持久化(配合 shared_preferences 或 Hive)。
4. 面试时别背概念,讲场景
当被问“你怎么选状态管理方案”,别说“BLoC 更好因为响应式”。要说:
“我们上个项目有 20+ 页面共享用户状态,初期用 Provider 导致 rebuild 过多,后来迁移到 Riverpod,通过
select优化监听粒度,帧率从 52 提升到 58。”
用数据和结果说话,比背八股文强一百倍。
从外包到甲方,我最大的成长不是技术
上周五晚上,我和老婆在西华路吃牛杂,她问我:“最近加班少好多,是不是甲方舒服点?”
我笑着说:“不是舒服,是做事有章法了。以前在外包,天天救火;现在在甲方,我们在造消防系统。”
其实 Flutter 状态管理只是表象,背后是工程思维的升级。外包教会我快速交付,甲方教会我如何构建可持续演进的系统。而 GPT-4 这类工具,不是用来抄答案的,而是帮我们快速验证思路、查漏补缺——就像当年我师傅教我用 Google 一样。
如果你也在外包,想跳甲方,别怕。我月薪15k的时候也觉得自己没戏。但只要你在每个项目里多问一句“有没有更好的方式”,多花一小时研究官方文档,机会总会来。
程序员最怕的不是技术难,而是停止思考。
最后一点真心话
今年三月,我带了一个实习生,也是老广,华工毕业的。他第一天就问我:“哥,状态管理到底该学哪个?网上说法太多了。”
我泡了壶普洱,慢慢说:“没有银弹。但你可以记住三件事:
- 先理解问题,再选工具。状态管理的本质是“当数据变,视图自动更新”。
- 保持简单。能用 10 行代码解决的,别写 100 行架构。
- 写给人看,不是给机器跑。半年后你自己都看不懂的代码,就是垃圾。
他似懂非懂地点头。我想,这大概就是传承吧。
现在的我,依然会在深夜 debug 时骂一句“顶你个肺”,但心里踏实多了。因为我知道,自己写的每一行代码,都在为一个真实的产品服务,而不是某个明天就消失的外包需求。
共勉。

评论 0