移动应用架构设计:MVVM实战

南城开发者
2025-06-16 19:17
阅读 243

一、开篇:什么是MVVM?它能用来做什么?

一、开篇:什么是MVVM?它能用来做什么?

大家好,我是你的移动开发讲师!今天我们来聊聊 MVVM,这是目前 Android 和 iOS 开发中非常流行的一种应用架构模式。

1.1 MVVM 是什么?

MVVM 的全称是 Model-View-ViewModel。我们来打个比方:

假设你正在做一道菜(比如西红柿炒蛋),那么:

  • Model 就是你用的食材(鸡蛋、西红柿);
  • View 就是你端上桌的成品菜;
  • ViewModel 就是厨师(你),负责把食材处理成可以上菜的样子。

在 App 开发中,MVVM 的作用就是让界面(View)和数据处理(Model)解耦,提升代码的可维护性、测试性和清晰度。

1.2 为什么要学习 MVVM?

  • ✅ 分工明确,结构清晰
  • ✅ 数据绑定简单,更新页面更容易
  • ✅ 更容易写单元测试
  • ✅ 是现在主流框架(如 Jetpack Compose、SwiftUI、Vue.js 等)的基础思想之一

二、环境准备:开始之前,你需要这些工具

二、环境准备:开始之前,你需要这些工具

为了让你更好地体验 MVVM 模式,我们选择使用 Android 平台 + Kotlin + Android Studio 来演示。如果你是 iOS 用户,也可以参考类似的 MVC/MVVM 结构,但我们这里以 Android 为主。

2.1 安装 Android Studio(最新稳定版)

  1. 访问 Android Studio 官网
  2. 下载并安装(支持 Windows / macOS / Linux)
  3. 打开后创建一个新项目,选择 Empty Activity
  4. 编程语言选择 Kotlin

2.2 添加必要的依赖库

打开 build.gradle (Module) 文件,在 dependencies 部分添加以下内容:

implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1'
implementation 'androidx.activity:activity-ktx:1.7.2'

这些库可以帮助我们更轻松地实现 MVVM 架构中的 ViewModel 和生命周期管理。


三、核心概念讲解:MVVM 的三大角色

三、核心概念讲解:MVVM 的三大角色

MVVM 包含三个主要部分:

名称 英文缩写 职责说明
模型层 Model 负责获取/存储数据,例如网络请求或数据库
视图模型层 ViewModel 处理逻辑,连接 Model 和 View
视图层 View 显示界面,响应用户操作

让我们用最简单的语言解释一下它们是怎么配合工作的:

3.1 Model:你是谁?从哪来?

Model 是你的数据来源。比如你要显示一个用户的姓名,那 Model 就是从网络或者本地数据库拿回来的数据。

示例代码:User.kt

data class User(val name: String, val age: Int)

再比如你可以通过 API 获取用户数据:

class UserRepository {
    fun getUser(): User {
        // 这里可以替换成真实的网络请求
        return User("张三", 25)
    }
}

3.2 ViewModel:你是大脑

ViewModel 是你的“中间人”。它不直接操作界面,但知道怎么处理数据,并且能监听数据变化去通知界面更新。

示例代码:MainViewModel.kt

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

class MainViewModel : ViewModel() {
    private val _user = MutableStateFlow(User("", 0))
    val user: StateFlow<User> = _user

    private val repository = UserRepository()

    fun loadUser() {
        viewModelScope.launch {
            val fetchedUser = repository.getUser()
            _user.value = fetchedUser
        }
    }
}

注意:这里用了 StateFlow 来管理状态,方便后续观察数据变化。

3.3 View:你是脸面

View 就是我们常见的布局文件(XML),以及与之关联的 ActivityFragment,负责展示数据。

示例代码:MainActivity.kt

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private val viewModel: MainViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 观察数据变化
        lifecycleScope.launch {
            viewModel.user.collect {
                binding.textView.text = "姓名:${it.name}, 年龄:${it.age}"
            }
        }

        // 点击按钮加载数据
        binding.button.setOnClickListener {
            viewModel.loadUser()
        }
    }
}

对应的界面文件 activity_main.xml 内容如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:padding="16dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:text="加载用户信息"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/textView"
        android:layout_marginTop="16dp"
        android:textSize="18sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

四、实战项目:跟着我一步一步做一个 MVVM 项目吧!

四、实战项目:跟着我一步一步做一个 MVVM 项目吧!

我们现在来一步步完成一个 显示当前天气情况的 App,感受一下 MVVM 的威力。

4.1 功能需求

  • 用户点击按钮,模拟加载城市天气数据
  • 展示城市名称、气温、是否下雨
  • 使用 MVVM 架构分层清晰

4.2 第一步:创建 Model

创建文件 Weather.kt

data class Weather(
    val city: String,
    val temperature: Double,
    val isRainy: Boolean
)

创建仓库类 WeatherRepository.kt

class WeatherRepository {
    fun getWeather(city: String): Weather {
        // 可替换为真实API调用
        return Weather(city, 25.5, true)
    }
}

4.3 第二步:创建 ViewModel

创建文件 WeatherViewModel.kt

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.*

class WeatherViewModel : ViewModel() {
    private val _weather = MutableStateFlow(Weather("", 0.0, false))
    val weather: StateFlow<Weather> = _weather

    private val repository = WeatherRepository()

    fun fetchWeather(city: String) {
        viewModelScope.launch {
            val result = repository.getWeather(city)
            _weather.value = result
        }
    }
}

4.4 第三步:创建 View

编辑 activity_weather.xml

<LinearLayout ... >
    <EditText
        android:id="@+id/editTextCity"
        android:hint="输入城市名"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/buttonFetch"
        android:text="查询天气"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/textViewResult"
        android:textSize="18sp"
        android:layout_marginTop="16dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

编写 WeatherActivity.kt

class WeatherActivity : AppCompatActivity() {
    private lateinit var binding: ActivityWeatherBinding
    private val viewModel: WeatherViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityWeatherBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 监听天气数据变化
        lifecycleScope.launch {
            viewModel.weather.collect { weather ->
                val rainStatus = if(weather.isRainy) "下雨" else "晴天"
                binding.textViewResult.text =
                    "城市:${weather.city}\n温度:${weather.temperature}℃\n天气:$rainStatus"
            }
        }

        binding.buttonFetch.setOnClickListener {
            val city = binding.editTextCity.text.toString()
            viewModel.fetchWeather(city)
        }
    }
}

✅ 到此为止,我们的 MVVM 示例就完成了!运行后应该能看到效果。


五、新手常见问题解答

5.1 为什么需要 ViewModel?

ViewModel 在页面旋转等配置变更时不会被销毁,保证了数据持久化,避免重复请求数据。

5.2 我可以在 ViewModel 中直接修改 UI 吗?

不可以!ViewModel 不应该持有对 View 的引用,这违反了 MVVM 的分层原则。

5.3 ViewModel 和 LiveData 有什么区别?

  • LiveData 是一种可观察的数据对象,主要用于传统 XML 布局绑定。
  • StateFlow 是 Kotlin 协程中的流,功能更强大,推荐用于现代开发。

六、学习建议:下一步该怎么走?

恭喜你完成了第一个 MVVM 项目!

接下来你可以尝试:

6.1 提升难度:加入 Room 数据库

试着将 Model 层改为本地数据库读取,使用 Room 库,实现离线缓存。

6.2 引入网络请求:搭配 Retrofit

repository 改成从网络接口获取真实数据。

6.3 学习 Jetpack Compose

使用 Jetpack Compose 替代 XML 布局,结合 MVVM,打造现代化 UI。


总结

本篇文章我们一起了解了 MVVM 架构的基本原理和应用场景,并通过一个完整的例子实现了基于 MVVM 的天气查询 App。虽然看起来有点复杂,但只要你按照步骤一步步来,很快就能掌握它的核心思想。

🔑 关键词回顾:

  • Model:数据源
  • ViewModel:中间大脑,连接 Model 和 View
  • View:展示界面

希望这篇教程能成为你进入移动开发架构世界的第一步。有问题欢迎留言,我会及时回答你们的问题!

继续加油,未来的 Android 大神就在我们中间 👨‍💻✨

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝