2026 已过 1/3:事豫则立,不预则废——关于架构、协程与边界的思考

《礼记·中庸》里有句话:「凡事豫则立,不预则废。」 放在写代码这件事上,其实也一样成立。

2026 已经过去三分之一了。 我回头翻了一下这三个月写下的东西,总结总结。


一、先看一眼这些"产出"

三个月,10+ 篇文章,大致分布在四个方向:

  • Clean Architecture 落地实践(5 篇)
  • 协程与并发模型(3 篇)
  • Android 现代化演进(3 篇)
  • 工具链 & 方法论(2 篇)

数量不算多,但有个挺有意思的共同点------ 几乎每一篇,都是在讲一件事:

先告诉你"这样写会出事",再告诉你"应该怎么写"。

一开始不是刻意这么写的, 但回头看才意识到,这可能是这段时间我最想表达的核心:

知道"不该做什么",往往比知道"该做什么"更重要。


二、这 10+ 篇,其实在反复讲同一件事

2.1 架构:分层不是为了好看,是为了"有边界"

这一组,是整个系列的骨架。

写《送外卖》那篇的时候,我其实就想干一件事: 把 Clean Architecture 讲到不需要背景知识也能听懂

老板 / 餐厅 / 外卖员,对应三层架构。 一句话总结就是:

老板不该关心外卖员骑的是电动车还是摩托车。

翻译成代码就是:

Domain 层不应该知道外层的任何实现细节。

后面的 Demo、UseCase、Repository,本质都在补同一个点:

  • UI 不该碰业务规则
  • UseCase 不该变"调度中心"
  • Manager 不该成为"上帝类"

这些看似不同的问题,背后其实是同一个错误:

边界没守住。

分层真正的意义,从来不是"结构好看",而是:

  • 可以单独改
  • 可以单独测
  • 不会牵一发而动全身

2.2 协程:别再用"线程思维"写协程了

这一组,是我写得最爽的一部分。

因为几乎每一篇,都在拆一个常见误区:

  • UseCase 里 ioScope.launch ------ ❌
  • ViewModel 里 Dispatchers.IO ------ ❌
  • try-catch 直接兜底 ------ ❌
  • synchronized / ReentrantLock ------ ❌

问题看起来五花八门,但本质只有一个:

你在用"线程的脑子",写"协程的代码"。

比如那篇锁的文章,其实一句话就能说清:

JUC 锁的是线程,协程压根不保证跑在同一个线程上。

这就是为什么它要么编译不过,要么运行期炸。

所以结论也很干脆:

协程时代,锁应该属于"协程",而不是"线程"。

再往上抽一层,就是这一组的核心:

协程不是线程的语法糖,它是一整套新的并发模型。


2.3 现代化:不是 API 变了,是"责任被接管了"

这一组其实在回答一个问题:

为什么这些老东西,一个个都"不推荐用了"?

Handler、SharedPreferences、手动管理生命周期......

不是它们"错了",而是:

它们把太多本该自动处理的事情,交给了开发者自己。

而现代方案在做的事,其实很统一:

  • lifecycleScope:帮你管生命周期
  • DataStore:帮你管并发 + IO
  • Flow:帮你管数据流动

总结成一句话就是:

把"人肉维护",变成"架构托管"。

这才是 Android 这几年的真正演进方向。


2.4 方法论:把"异步语义"写进类型系统

异步不再是实现细节,而是接口本身的语义。

进一步抽象,其实就是一条隐性的设计规范:

  • suspend:表达一次性结果
  • Flow:表达持续变化的数据

因此:

我们不是在"处理异步",而是在"用类型定义数据的行为"。

这也是为什么------

接口一旦设计好,异步就不再需要讨论。

这一点,我觉得比任何 API 技巧都更重要。


三、这三个月,我在表达上的转变

1. 比喻,比代码难写多了

《送外卖》那篇,比任何一篇技术文都费劲。

因为你要做到三件事同时成立:

  • 直觉上好理解
  • 逻辑上不失真
  • 不误导读者

这个平衡,其实挺难的。


2. "反模式"更有杀伤力

直接讲"最佳实践",很多人是没感觉的。

但你只要给他看:

  • 锁在协程里炸掉
  • apply() 卡主线程
  • 业务逻辑写散导致线上 bug

基本不用你解释,他自己就懂了。

坏结果,比原则更有说服力。


3. API 会变,但设计不会

DataStore、Room、Flow......

如果只停在"怎么用",其实很容易过时。

但如果你理解的是:

  • 为什么是 Actor 模型
  • 为什么是 Flow
  • 为什么是单向数据流

四、关于 MVVM 和 MVI:从"网"到"线"

4.1 MVVM:容易变成"状态网"

在常见 MVVM 写法中:

  • ViewModel 中存在多个状态:

    • loading
    • items
    • error
  • View 层分别订阅多个状态源

  • UI 更新分散在多个地方

随着业务复杂度上升:

  • 状态之间缺乏统一关系
  • 状态更新路径不清晰
  • 调试困难

最终演变为:

一张复杂的"状态网"


4.2 MVI:将状态收敛为"一条线"

MVI 的核心思想是:

  • 单一状态源(Single Source of Truth)
  • 单向数据流(Unidirectional Data Flow)
  • 所有事件统一入口

典型结构:

View → Intent → Reducer → State → View

所有状态变化,都遵循:

从一个状态 → 下一个状态 → 再下一个状态

五、总结

「事豫则立,不预则废。」

这三个月写的这些东西,其实都在反复强调一件事:

在写代码之前,把边界、职责、抽象层级想清楚。

很多问题,不是代码写错了, 而是

一开始就没想清楚。

系列文章索引(持续更新)

分类 文章
Clean Architecture 从送外卖看 Android Clean 架构
Clean Architecture 用一个小 Demo 带你入门 Clean Architecture
Clean Architecture UseCase 的「守边计划」:不启动协程,不切线程,但可以并发
Clean Architecture 为什么 UI 不建议直接访问 Repository
Clean Architecture 是时候告别 Manager 了
协程 协程中的三大反模式
协程 ViewModel 不该处理异常
协程 协程时代,出现 ReentrantLock 就是架构警报
Android 现代化 Handler 在协程时代的退场
Android 现代化 内存泄漏的现代解法
Android 现代化 为什么 Google 不再推荐 SharedPreferences
工具与方法论 先用 IntelliJ 学透 Kotlin 协程,再进入 Android
工具与方法论 suspend 与 Flow 的接口语义规范
相关推荐
冬奇Lab2 小时前
Android 15 音频子系统(八):Audio HAL 与硬件接口——音频数据的最后一公里
android·音视频开发·源码阅读
黄林晴5 小时前
Compose Multiplatform 1.10 发布:里程碑式更新!
android
流星白龙5 小时前
【MySQL】19.MySQL用户管理
android·mysql·adb
匆忙拥挤repeat5 小时前
Android Compose 可组合项的生命周期、副作用API
android
hnlgzb6 小时前
目前编写安卓app的话有哪几种设计模式?
android·设计模式·kotlin·android jetpack·compose
studyForMokey7 小时前
【Android面试】Fragment生命周期专题
android·microsoft·面试
Android系统攻城狮8 小时前
Android tinyalsa深度解析之pcm_plugin_open调用流程与实战(一百七十四)
android·pcm·tinyalsa·音频进阶手册
用户622386252179 小时前
Android 列表控件实战:从 ListView 到 RecyclerView,仿今日头条 HeadLine 项目全解析
android
呦呼4579 小时前
Android 仿今日头条项目分析
android