Android 架构演进全解析:MVC、MVP、MVVM、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()
val password = MutableLiveData()
val result = MutableLiveData()
fun login() {
result.value = if (username.value == "admin" && password.value == "1234")
"登录成功" else "登录失败"
}
}
class LoginActivity : AppCompatActivity() {
private val vm by viewModels()
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 = _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 | 双向 | 简单易懂 | 耦合高 | 小型项目 |
| MVP | 单向 | 解耦清晰,可测试 | 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。
浙公网安备 33010602011771号