Android 架构演进全解析:MVC、MVP、MVVM、MVI 图文详解
前言:
从命令式到响应式,从混乱到优雅。
一文彻底搞懂 Android 四大架构模式。
🧩 一、MVC(Model-View-Controller)
🧠 核心思想
最经典的架构,三层分工:
Model:数据层(网络、本地、业务逻辑)
View:视图层(XML、Activity、Fragment)
Controller:控制层(Activity 同时充当)
🧱 架构关系图
graph TDA[View] -->|用户操作| B[Controller]B -->|调用| C[Model]C -->|返回数据| BB -->|更新| A
🔁 交互流程图:用户操作 → 数据更新 → 界面刷新
sequenceDiagramparticipant U as 用户participant V as View (Activity)participant M as ModelU->>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 TDA[View] -->|事件| B[Presenter]B -->|调用| C[Model]C -->|结果| BB -->|更新UI| A
🔁 交互流程图
sequenceDiagramparticipant U as 用户participant V as Viewparticipant P as Presenterparticipant M as ModelU->>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 TDA[View] <--> B[ViewModel]B -->|调用| C[Model]C -->|数据返回| B
🔁 交互流程图(基于 LiveData / Flow)
sequenceDiagramparticipant U as 用户participant V as Viewparticipant VM as ViewModelparticipant M as ModelU->>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 = vmbinding.lifecycleOwner = this}
}
🧩 四、MVI(Model-View-Intent)
🧠 核心思想
采用 单向数据流(Unidirectional Data Flow):
用户意图(Intent)→ 状态更新(State)→ UI 渲染(Render)。
🧱 架构关系图
graph LRA[View] -->|Intent| B[ViewModel]B -->|Action| C[Model]C -->|Result| BB -->|New State| A
🔁 交互流程图(单向数据流)
sequenceDiagramparticipant U as 用户participant V as Viewparticipant VM as ViewModelparticipant M as ModelU->>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> = _statefun 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。