
站在 2025 年回望,Android 开发已走过近二十年。从早期“Activity 即一切”的野蛮生长,到如今以 Jetpack Compose + Kotlin Coroutines + Clean Architecture 为核心的现代开发范式,应用架构的演进不仅是技术的升级,更是工程思维的成熟。
在这条演进之路上,MVC、MVP、MVVM 三大模式如同三座里程碑,分别代表了 Android 社区在不同阶段对关注点分离(Separation of Concerns)、可测试性(Testability) 和状态管理(State Management) 的探索与突破。今天,我们不仅回顾它们“是什么”,更要理解它们“为何而来”、“因何而去”,以及它们如何共同塑造了今日 Android 开发的底层逻辑。
在架构意识尚未觉醒的年代,一个典型的 MainActivity 往往集万千职责于一身:
findViewById 操作 UI 控件;onCreate() 中处理业务逻辑分支;onActivityResult() 中解析 Intent 数据;AsyncTask 处理异步任务……这种“上帝类”模式看似高效,实则埋下巨大隐患:
问题维度 | 具体表现 |
|---|---|
高耦合 | UI、网络、DB、业务逻辑全部交织,修改一处可能引发连锁崩溃 |
不可测试 | 业务逻辑强依赖 Context、Activity 等 Android SDK 类型,无法脱离设备运行单元测试 |
状态脆弱 | 屏幕旋转导致 Activity 重建,未妥善保存的数据(如网络加载中的状态)瞬间丢失 |
维护地狱 | 单文件超 2000 行代码,新人接手需数周才能理清逻辑 |
正是这种“开发快、维护慢、测试难”的恶性循环,催生了对架构模式的迫切需求。而第一个被引入的,便是软件工程的经典范式——MVC。
MVC 的核心在于三者职责分离:
但在 Android 中,没有独立的 Controller。Activity / Fragment 被迫同时承担 View(UI 渲染) 和 Controller(事件处理) 双重角色:
+------------------+
| Model | ←→ (数据)
+------------------+
↑
| (调用/回调)
+-------------------------------+
| Activity/Fragment (V + C) |
| - setContentView() |
| - findViewById() |
| - onClick() { |
| model.fetchData(); |
| updateUI(); |
| } |
+-------------------------------+
↑
| (布局引用)
+------------------+
| XML Layout | ← (View)
+------------------+贡献:
局限:
Activity 既是 View 又是 Controller,解耦不彻底。Activity 中,无法进行纯 JVM 单元测试。2025 年回看:MVC 更像是一次“思想启蒙”,而非实用方案。它暴露了 Android 框架设计与经典 MVC 的天然冲突,为 MVP 的登场埋下伏笔。
MVP 通过引入 Presenter 彻底切断 View 与 Model 的直接联系,实现“被动视图”理念。
Activity / Fragment 实现的接口,仅暴露 UI 操作方法(如 showLoading()、updateList())。

样板代码爆炸:
interface MainContract {
interface View {
fun showUsers(users: List<User>)
fun showError(msg: String)
}
interface Presenter {
fun loadUsers()
}
}每个页面需定义 Contract 接口,Presenter 与 View 方法一一对应。
生命周期陷阱:
onSaveInstanceState / onRestoreInstanceState 保存 Presenter 状态。Presenter 肿胀:复杂页面的所有逻辑涌入 Presenter,演变为“新上帝类”。
2025 年反思:MVP 是“为了解耦而解耦”的典型。它解决了 MVC 的痛点,却引入了新的复杂性。其兴盛(约 2016–2019)恰逢 Android 单元测试文化兴起,但最终被更优雅的 MVVM 取代。
MVVM 的崛起,离不开 Google Jetpack 的强力推动。它不再依赖“接口回调”,而是通过 可观察数据 + 生命周期感知 实现自动同步。
androidx.lifecycle.ViewModel,持有 LiveData / StateFlow 封装的 UI 状态。Activity / Fragment 通过 observe() 监听状态变化,自动更新 UI。class MainViewModel : ViewModel() {
private val _users = MutableLiveData<List<User>>()
val users: LiveData<List<User>> = _users
fun loadUsers() {
viewModelScope.launch {
_users.value = repository.getUsers()
}
}
}
// Activity 中
viewModel.users.observe(this) { users ->
adapter.submitList(users)
}setText() / notifyDataSetChanged()。LiveData 仅在 LifecycleOwner(如 Activity)处于 STARTED/RESUMED 时通知,避免空指针与内存泄漏。ViewModel 由 ViewModelProvider 管理,在屏幕旋转等场景下自动保留实例。ViewModel 不依赖 Android Context,可轻松单元测试。2025 年现状:MVVM 已成为 Android 官方推荐架构的核心,尤其与 Jetpack Compose 结合后,形成“状态驱动 UI”的终极形态。
MVVM 并非终点。随着应用复杂度提升与声明式 UI 的普及,新一代架构思想正在融合演进:
MVI 将用户操作抽象为 Intent,状态变更通过 Reducer 生成新 State,形成严格单向流:
sealed class MainIntent {
object LoadUsers : MainIntent()
}
data class MainState(
val isLoading: Boolean = false,
val users: List<User> = emptyList(),
val error: String? = null
)
class MainViewModel : ViewModel() {
private val _state = MutableStateFlow(MainState())
val state: StateFlow<MainState> = _state.asStateFlow()
fun processIntent(intent: MainIntent) {
when (intent) {
is MainIntent.LoadUsers -> loadUsers()
}
}
private fun loadUsers() {
// 更新 state via _state.update { ... }
}
}优势:状态可预测、可回溯、易于时间旅行调试(Time Travel Debugging)。
契合 Compose:Compose 的 @Composable 函数天然适配“State → UI”映射。
Google 在 Guide to app architecture 中明确推荐三层架构:
┌──────────────┐
│ UI Layer │ ← ViewModel + Compose/ViewBinding
├──────────────┤
│ Domain Layer │ ← UseCase (封装复杂业务)
├──────────────┤
│ Data Layer │ ← Repository + DataSource (Retrofit, Room)
└──────────────┘LiveData 逐渐被 StateFlow / SharedFlow 取代,因其支持冷流、背压、组合操作符。维度 | MVC | MVP | MVVM | MVI(2025) |
|---|---|---|---|---|
状态持有者 | Activity | Presenter | ViewModel | StateFlow |
UI 更新方式 | 手动调用 | 回调接口 | 观察数据 | 响应状态 |
生命周期管理 | 手动 | 手动(易错) | 自动 | 自动 |
可测试性 | 差 | 好 | 极好 | 极好 |
核心哲学 | 分离职责 | 彻底解耦 | 数据驱动 | 单向数据流 |
架构没有银弹,只有权衡(Trade-offs)。 MVC 教会我们“分层”,MVP 教会我们“解耦”,MVVM 教会我们“响应式”,MVI 教会我们“状态即真理”。
站在 2025 年,我们不再争论“用 MVP 还是 MVVM”,而是思考:
而这一切的起点,正是当年那个试图从“上帝 Activity”中挣脱出来的你。
结语: 理解 MVC、MVP、MVVM,不是为了怀旧,而是为了看清—— 所有架构的本质,都是对“复杂性”的驯服。 愿你在未来的代码中,始终握紧这把名为“关注点分离”的罗盘。