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 / MVPActivity + Presenter
中型项目MVVMViewModel + LiveData / Flow
大型 / Compose 项目MVIStateFlow + Jetpack Compose

七、总结

Android 架构从 MVC → MVI 是 逻辑解耦与状态统一 的演化。

  • 想简单快速?用 MVP

  • 想响应式更新?用 MVVM

  • 想更函数式、更现代?选 MVI

posted on 2025-11-14 16:09  ljbguanli  阅读(179)  评论(0)    收藏  举报