Android 架构演进全解析:MVC、MVP、MVVM、MVI 图文详解

179 阅读5分钟

前言:

从命令式到响应式,从混乱到优雅。
一文彻底搞懂 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 ↔ ModelPresenter 负责协调 View 和 Model,View 与 Presenter 通信,Presenter 调用 Model 获取数据后回调 View。解耦清晰,可单元测试 PresenterPresenter 代码量大、接口冗余中型项目,逻辑较复杂但未用 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 / MVPActivity + Presenter
中型项目MVVMViewModel + LiveData / Flow
大型 / Compose 项目MVIStateFlow + Jetpack Compose

💬 九、总结

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

  • 想简单快速?用 MVP
  • 想响应式更新?用 MVVM
  • 想更函数式、更现代?选 MVI