请写一篇关于【移动应用架构设计:MVVM实战】的技术文章
去年十月,广州下着小雨。我坐在天河北一栋老写字楼的会议室里,面前是字节跳动的面试官,手里捏着一张被汗水微微浸湿的简历。那一刻,我脑子里全是“完蛋了”三个字。
不是因为题太难——那天考的是 MVVM 架构在 Android 中的具体落地细节,而是因为我根本没系统整理过自己的项目经验。虽然我在上一家公司确实用过 ViewModel + LiveData + Repository 搞了一整套数据流,但一被问到“为什么选择 MVVM 而不是 MVP?生命周期怎么管理?如何做单元测试?”我就开始语无伦次。
“你这个架构……看起来像是把官方 demo 改了改?”面试官皱着眉头说。
我尴尬地笑了笑:“差不多吧,反正能跑就行。”
那天回去的路上,地铁三号线挤得像沙丁鱼罐头。我靠在门边,耳机里放着《海阔天空》,心里却堵得慌。月薪15k,在广州老城区租个3500的房子,养活自己没问题,但离“大厂梦”还差十万八千里。更别说老婆刚怀孕,我连奶粉钱都得精打细算。
从二本毕业到大厂边缘:我的技术债
我是广东某二本院校计算机专业毕业的。大学那会儿,除了打 LOL 和追剧,代码写得不多。毕业后第一份工作是在天河一家外包公司,每天就是接需求、改 UI、修 bug,产品原型图一丢过来,我们就开干,哪管什么架构不架构。
后来跳槽到一家做本地生活 App 的创业公司,团队不到十人。老板拍脑袋定需求,产品经理三天两头改方案,前端后端全靠微信对齐。有次上线前夜,产品经理突然说“首页要加个轮播广告位”,我和 iOS 同事对视一眼,只能硬着头皮改。结果第二天线上 crash 率飙到 8%,用户投诉不断。
那时候我开始意识到:光会写代码不够,得懂“产品”背后的逻辑,更得有自己的“资源”意识——不仅是服务器资源、内存资源,更是时间资源、人力成本、维护成本。
但真正让我下定决心系统学习架构设计的,是一次失败的求职。
2022 年底,我投了腾讯。面试官问我:“你们 App 是怎么处理网络请求失败重试的?ViewModel 生命周期和 Activity 不一致时怎么处理数据丢失?”我支支吾吾说了几句,对方明显失望了。
回家后,老婆看我脸色不对,问我:“又挂了?”
我点点头,叹了口气:“感觉自己像个码农,不是工程师。”
她摸摸我的头:“那你就好好学呗。反正你现在工资也够活,别怕慢。”
那晚我翻出 Google 官方的 Architecture Components 文档,从头看到尾。不是为了应付面试,而是真的想知道:一个好的移动应用,到底该怎么搭骨架?
MVVM 不是银弹,但它是起点
很多人以为 MVVM 就是 ViewModel + LiveData + DataBinding,其实这是误区。MVVM 的核心,是解耦、可测试、可维护。
我拿我们公司那个本地生活 App 举个例子。最初版本,所有逻辑都塞在 Activity 里:
public class HomeActivity extends AppCompatActivity {
private void loadData() {
Api.getService().getHomeData()
.enqueue(new Callback<HomeData>() {
@Override
public void onResponse(...) {
// 直接操作 UI
bannerView.setData(response.data);
listAdapter.update(response.list);
}
});
}
}
乍一看没问题,但一旦需求变更——比如要加缓存、要支持离线、要加 loading 状态、要处理 token 过期——代码立马变成意大利面条。更别说单元测试?根本没法测!
后来我重构了一版,引入 MVVM:
- Model 层:Repository 统一管理数据源(网络 + 本地数据库),对外暴露 LiveData。
- View 层:Activity/Fragment 只负责监听状态变化、更新 UI。
- ViewModel 层:持有业务逻辑,不持有 Context,生命周期安全。
关键改进在于:把“产品需求”翻译成“状态流”。
比如产品说:“用户进入首页,如果没网,就显示上次缓存的数据,并提示‘当前无网络’。”
以前我会在 Activity 里写一堆 if-else 判断网络状态、缓存是否存在……
现在,我在 ViewModel 里定义一个 UiState:
data class HomeUiState(
val isLoading: Boolean = false,
val data: HomeData? = null,
val error: String? = null,
val isOffline: Boolean = false
)
然后通过 LiveData<HomeUiState> 推送给 View。View 只需根据状态决定显示什么,完全不用关心“数据从哪来”“怎么来的”。
这看似简单,但背后是对“产品意图”的深度理解。好的架构师,首先是好的产品经理翻译官。
资源有限?那就更要用好 MVVM
很多人说:“我们团队小,没时间搞架构,能跑就行。”
这话我以前也信。但现实是:越是资源紧张的小团队,越需要清晰的架构——因为返工成本太高了。
记得有次产品临时要加“夜间模式”。旧代码里颜色值散落在各个 XML 和 Java 文件里,改起来像考古。而新架构下,我把主题配置抽象成 ThemeManager,UI 元素通过资源 ID 引用,切换主题只需一行代码。
还有一次,测试同学抱怨:“这个页面的加载逻辑太复杂,我们测不过来。”
我直接给她看 ViewModel 的单元测试:
@Test
fun `when load success, emit data`() {
coEvery { repository.getHomeData() } returns mockData
viewModel.load()
assert(viewModel.uiState.value.data == mockData)
}
她眼睛一亮:“原来还能这样?”
你看,架构不是炫技,而是降低协作成本、提升交付确定性。在资源有限的情况下,这比加班改 bug 实在多了。
求职时,别只背八股文
回到开头那场字节面试。后来我复盘发现,面试官真正在意的不是 MVVM 的定义,而是:
- 你有没有思考过“为什么”?为什么选这个架构?它解决了什么问题?
- 你有没有权衡过取舍?比如用 Flow 还是 LiveData?协程作用域怎么管理?
- 你能不能把技术语言翻译成业务价值?比如“用 MVVM 后,新功能开发速度提升 30%”。
所以后来我准备面试,不再死记“ViewModel 不会随配置变化销毁”,而是讲清楚:
“我们在做商品详情页时,用户旋转屏幕会导致 Activity 重建。以前数据会重新请求,浪费流量还卡顿。用了 ViewModel 后,数据保留在内存中,UI 重建时直接恢复,用户体验流畅很多。产品同事都说这次改得好。”
技术是手段,产品是目的,资源是约束,而求职,是你展示“解决问题能力”的舞台。
今年三月,我又面了字节。这次我带了一份架构演进文档,从 MVC 到 MVP 再到 MVVM,每一步都写了业务背景、痛点、收益。面试官看完笑了:“你这不像外包出来的啊。”
最后 offer 到手,月薪 22k。虽然不算高,但对我这个二本出身的老广程序员来说,已是逆袭。
写给还在挣扎的你
我知道,很多人和我一样:学历一般、起点不高、每天被需求追着跑,还要担心 35 岁危机。但我想说:技术这条路,拼的不是谁起跑快,而是谁能持续进化。
MVVM 不是什么高深魔法,它只是帮你把混乱的需求、有限的资源、复杂的协作,理出一条清晰的线。而这条线,最终会引向更好的产品、更高的效率,以及——一份让你挺直腰板的 offer。
上周五晚上,我坐在珠江新城的办公室,窗外是猎德大桥的霓虹。手机震动,老婆发来消息:“宝宝会翻身了!”
我回了个笑脸,然后继续调试手里的 Compose + MVVM 新项目。这一次,我不再焦虑。
因为我知道:只要还在写代码,就还有机会。
最后的几点建议
- 别为了用 MVVM 而用 MVVM。如果项目很简单(比如一个设置页),MVC 也够用。架构服务于业务,不是反过来。
- 重视测试。哪怕只写 ViewModel 的单元测试,也能极大提升信心。
- 学会画图。用一张架构图向产品、测试、新人解释你的设计,比写一万行注释都有效。
- 把每次重构当成求职作品集。未来面试时,这些故事比 LeetCode 刷题记录更有说服力。
- 保持对“产品”的敏感。多问一句“用户为什么要这个功能?”,你的代码会更有温度。
广州的夏天又来了,湿热,但充满生机。就像我们这些普通程序员的人生——起点不高,但每一步,都算数。

评论 0