前言:

从命令式到响应式,从混乱到优雅。
一文彻底搞懂 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

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐