Android 架构演进全解析:MVC、MVP、MVVM、MVI 图文详解
从命令式到响应式,从混乱到优雅。一文彻底搞懂 Android 四大架构模式。模式数据流方向优点缺点推荐场景MVC双向简单易懂耦合高小型项目MVP单向解耦清晰,可测试Presenter 冗余中型项目MVVM双向响应式更新调试复杂Jetpack MVVM 项目MVI单向状态集中、可回溯实现复杂Compose / 新架构项目Android 架构从 MVC → MVI 是逻辑解耦与状态统一的演化。想简单快
前言:
从命令式到响应式,从混乱到优雅。
一文彻底搞懂 Android 四大架构模式。
🧩 一、MVC(Model-View-Controller)
🧠 核心思想
最经典的架构,三层分工:
-
Model:数据层(网络、本地、业务逻辑)
-
View:视图层(XML、Activity、Fragment)
-
Controller:控制层(Activity 同时充当)
🧱 架构关系图
graph TD A[View] -->|用户操作| B[Controller] B -->|调用| C[Model] C -->|返回数据| B B -->|更新| A
🔁 交互流程图:用户操作 → 数据更新 → 界面刷新
sequenceDiagram participant U as 用户 participant V as View (Activity) participant M as Model U->>V: 点击登录按钮 V->>M: 调用 login(username, password) M-->>V: 返回登录结果 V-->>U: 显示登录成功/失败
💡 优缺点分析
| 优点 | 缺点 |
|---|---|
| ✅ 架构简单,上手快 | ❌ Controller 与 View 耦合严重 |
| ✅ 小项目快速开发 | ❌ 难以复用与测试 |
💻 示例
class LoginActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
btnLogin.setOnClickListener {
val result = UserModel().login(etUsername.text.toString(), etPassword.text.toString())
tvResult.text = if (result) "登录成功" else "登录失败"
}
}
}
🧩 二、MVP(Model-View-Presenter)
🧠 核心思想
引入 Presenter 层,隔离 View 与 Model。
Presenter 负责业务逻辑、数据协调。
🧱 架构关系图
graph TD A[View] -->|事件| B[Presenter] B -->|调用| C[Model] C -->|结果| B B -->|更新UI| A
🔁 交互流程图
sequenceDiagram participant U as 用户 participant V as View participant P as Presenter participant M as Model U->>V: 点击登录 V->>P: 调用 presenter.login() P->>M: 调用 Model 验证 M-->>P: 返回结果 P-->>V: 更新界面 V-->>U: 显示登录结果
💡 优缺点分析
| 优点 | 缺点 |
|---|---|
| ✅ 解耦明显,易测试 | ❌ Presenter 容易臃肿 |
| ✅ View 接口清晰 | ❌ 生命周期复杂 |
💻 示例
interface LoginView {
fun onLoginSuccess()
fun onLoginFail()
}
class LoginPresenter(private val view: LoginView) {
fun login(username: String, password: String) {
if (username == "admin" && password == "1234") view.onLoginSuccess()
else view.onLoginFail()
}
}
class LoginActivity : AppCompatActivity(), LoginView {
private val presenter = LoginPresenter(this)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
btnLogin.setOnClickListener {
presenter.login(etUsername.text.toString(), etPassword.text.toString())
}
}
override fun onLoginSuccess() = toast("登录成功")
override fun onLoginFail() = toast("登录失败")
}
🧩 三、MVVM(Model-View-ViewModel)
🧠 核心思想
通过 双向数据绑定 实现 UI 自动响应数据变化。ViewModel 管理状态,View 仅负责展示。
🧱 架构关系图
graph TD A[View] <--> B[ViewModel] B -->|调用| C[Model] C -->|数据返回| B
🔁 交互流程图(基于 LiveData / Flow)
sequenceDiagram participant U as 用户 participant V as View participant VM as ViewModel participant M as Model U->>V: 输入用户名/密码,点击登录 V->>VM: 调用 login() VM->>M: 发起网络请求 M-->>VM: 返回结果 VM-->>V: 更新 LiveData -> UI 自动刷新
💡 优缺点分析
| 优点 | 缺点 |
|---|---|
| ✅ 响应式更新、双向绑定 | ❌ 数据绑定调试困难 |
| ✅ 解耦彻底、结构清晰 | ❌ 学习曲线较高 |
💻 示例(ViewModel + DataBinding)
class LoginViewModel : ViewModel() {
val username = MutableLiveData<String>()
val password = MutableLiveData<String>()
val result = MutableLiveData<String>()
fun login() {
result.value = if (username.value == "admin" && password.value == "1234")
"登录成功" else "登录失败"
}
}
class LoginActivity : AppCompatActivity() {
private val vm by viewModels<LoginViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityLoginBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.vm = vm
binding.lifecycleOwner = this
}
}
🧩 四、MVI(Model-View-Intent)
🧠 核心思想
采用 单向数据流(Unidirectional Data Flow):
用户意图(Intent)→ 状态更新(State)→ UI 渲染(Render)。
🧱 架构关系图
graph LR A[View] -->|Intent| B[ViewModel] B -->|Action| C[Model] C -->|Result| B B -->|New State| A
🔁 交互流程图(单向数据流)
sequenceDiagram participant U as 用户 participant V as View participant VM as ViewModel participant M as Model U->>V: 点击登录按钮 V->>VM: 发送 Intent(LoginIntent.Submit) VM->>M: 调用 Model 执行登录逻辑 M-->>VM: 返回结果 VM-->>V: 发出新 State(loading / success) V-->>U: 渲染新的 UI 状态
💡 优缺点分析
| 优点 | 缺点 |
|---|---|
| ✅ 状态可追踪、调试方便 | ❌ 实现复杂、代码量大 |
| ✅ 单向数据流,逻辑统一 | ❌ 学习曲线陡峭 |
| ✅ 特别适合 Jetpack Compose | ❌ 状态管理不当易内存占用 |
💻 示例(ViewModel + StateFlow)
data class LoginState(val loading: Boolean = false, val message: String = "")
sealed class LoginIntent {
data class Submit(val username: String, val password: String) : LoginIntent()
}
class LoginViewModel : ViewModel() {
private val _state = MutableStateFlow(LoginState())
val state: StateFlow<LoginState> = _state
fun dispatch(intent: LoginIntent) {
when (intent) {
is LoginIntent.Submit -> login(intent.username, intent.password)
}
}
private fun login(username: String, password: String) {
viewModelScope.launch {
_state.value = LoginState(loading = true)
delay(1000)
val success = username == "admin" && password == "1234"
_state.value = LoginState(
loading = false,
message = if (success) "登录成功" else "登录失败"
)
}
}
}
🧠 五、四大架构模式数据流关系分析
| 模式 | 实际数据流方向 | 说明 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|---|---|
| MVC (Model-View-Controller) | ✅ 部分双向:View → Controller → Model,Model → View(间接或直接) | Controller 负责业务逻辑,View 负责展示,但在 Android 中往往 Activity 兼任 Controller & View,因此 导致高度耦合。 | 简单易懂,开发速度快 | Activity 太臃肿,Model 与 View 绑定紧密,难以测试 | 早期小项目或 Demo |
| MVP (Model-View-Presenter) | ✅ 双向交互:View ↔ Presenter ↔ Model | Presenter 负责协调 View 和 Model,View 与 Presenter 通信,Presenter 调用 Model 获取数据后回调 View。 | 解耦清晰,可单元测试 Presenter | Presenter 代码量大、接口冗余 | 中型项目,逻辑较复杂但未用 Jetpack |
| MVVM (Model-View-ViewModel) | ✅ 双向(DataBinding)或单向(StateFlow) | View 通过 DataBinding / LiveData / Flow 观察 ViewModel 数据变化,实现响应式 UI。Model 与 ViewModel 通信单向。 | 响应式、可维护、官方支持 | 数据流调试复杂、DataBinding 容易混乱 | Jetpack MVVM 项目(XML + ViewModel + Flow) |
| MVI (Model-View-Intent) | ✅ 严格单向:View → Intent → Model → State → View | 一切状态集中在 State 中,UI 只订阅状态变化;无直接调用,数据流清晰、可回溯。 | 状态可追踪、并发安全 | 实现复杂、状态管理成本高 | Compose、Redux 式架构、大型项目 |
📊 六、图解数据流方向
1️⃣ MVC(半双向)
View <----> Controller <----> Model ↑ 有时 View 直接引用 Model,导致高耦合
2️⃣ MVP(完全双向)
View <----> Presenter <----> Model
-
View 调用 Presenter 逻辑方法
-
Presenter 回调 View 更新 UI
-
Presenter 调用 Model 取数据,Model 回调 Presenter 返回结果
3️⃣ MVVM(推荐单向数据流)
Model --> ViewModel --> View View(观察ViewModel) --> 用户交互 --> ViewModel
-
若使用 DataBinding,则变成双向;
-
若使用 Flow/StateFlow,则是单向数据流(更推荐)。
4️⃣ MVI(完全单向)
View -> Intent -> Model -> State -> View
-
无回调,全部基于状态;
-
与 Redux、Unidirectional Data Flow 类似。
🧩 七、修正版总结表
| 模式 | 数据流方向 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|---|
| MVC | 半双向(View 与 Model 可能互相依赖) | 简单直观 | 高耦合,Activity 臃肿 | 小型 Demo |
| MVP | 双向(View ↔ Presenter ↔ Model) | 解耦清晰,可测试 | Presenter 冗长 | 中型项目 |
| MVVM | 单向(或双向,取决于实现) | 响应式更新,官方推荐 | 调试复杂 | Jetpack MVVM 项目 |
| MVI | 单向(严格状态流) | 状态集中,可追溯 | 实现复杂 | Compose / 新架构 |
🧭 八、架构选型建议
| 项目规模 | 推荐架构 | 推荐技术栈 |
|---|---|---|
| 小型项目 | MVC / MVP | Activity + Presenter |
| 中型项目 | MVVM | ViewModel + LiveData / Flow |
| 大型 / Compose 项目 | MVI | StateFlow + Jetpack Compose |
💬 九、总结
Android 架构从 MVC → MVI 是 逻辑解耦与状态统一 的演化。
想简单快速?用 MVP。
想响应式更新?用 MVVM。
想更函数式、更现代?选 MVI。
更多推荐


所有评论(0)