• MVVM 架构和MVI架构的优缺点对比


    Jetpack MVVM 架构讲解

    MVVM(Model-View-ViewModel)架构是 Android 开发中一种常用的架构模式,利用 Android Jetpack 组件,可以更简洁和高效地实现 MVVM。以下是 MVVM 的各个组件及其职责:

    1. Model

      • 职责:处理数据逻辑,包括从网络或数据库获取数据。
      • 示例:使用 Room 数据库、网络请求库(如 Retrofit)等来实现数据获取和存储。
    2. View

      • 职责:展示 UI 并响应用户交互。View 直接绑定到 ViewModel,并观察 LiveData 的变化。
      • 示例:Activity、Fragment、XML 布局文件。
    3. ViewModel

      • 职责:为 View 提供数据,处理与 UI 相关的逻辑,确保配置更改(如屏幕旋转)不会丢失数据。
      • 示例:使用 LiveData 来保存数据并通知 View 更新。
    示例代码
    // Model
    @Entity(tableName = "user")
    data class User(
        @PrimaryKey val id: Int,
        val name: String
    )
    
    @Dao
    interface UserDao {
        @Query("SELECT * FROM user WHERE id = :userId")
        fun getUserById(userId: Int): LiveData<User>
    }
    
    @Database(entities = [User::class], version = 1)
    abstract class AppDatabase : RoomDatabase() {
        abstract fun userDao(): UserDao
    }
    
    // ViewModel
    class UserViewModel(application: Application) : AndroidViewModel(application) {
        private val userDao: UserDao = AppDatabase.getDatabase(application).userDao()
        private val _userId = MutableLiveData<Int>()
    
        val user: LiveData<User> = Transformations.switchMap(_userId) { id ->
            userDao.getUserById(id)
        }
    
        fun setUserId(id: Int) {
            _userId.value = id
        }
    }
    
    // View (Activity)
    class UserActivity : AppCompatActivity() {
        private lateinit var userViewModel: UserViewModel
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_user)
    
            userViewModel = ViewModelProvider(this).get(UserViewModel::class.java)
    
            userViewModel.user.observe(this, Observer { user ->
                // 更新 UI
                findViewById<TextView>(R.id.userName).text = user.name
            })
    
            // 设置用户 ID 以触发数据加载
            userViewModel.setUserId(1)
        }
    }
    

    MVI 架构讲解

    MVI(Model-View-Intent)是另一种架构模式,特别强调单一数据流和不可变状态。MVI 的核心思想是通过 Intent 驱动状态变化,并用单一的状态对象来描述整个 UI。

    1. Model

      • 职责:处理数据逻辑,包括从网络或数据库获取数据,类似 MVVM。
    2. View

      • 职责:展示 UI 并响应用户交互,渲染单一的状态对象。
      • 示例:Activity、Fragment、XML 布局文件。
    3. Intent

      • 职责:用户意图的封装,触发状态变化。
      • 示例:点击按钮、输入文本等用户操作。
    4. State

      • 职责:表示 UI 的单一状态。
      • 示例:数据类包含所有 UI 所需的数据。
    示例代码
    // State
    data class UserState(
        val user: User? = null,
        val isLoading: Boolean = false,
        val error: String? = null
    )
    
    // Intent
    sealed class UserIntent {
        data class LoadUser(val userId: Int) : UserIntent()
    }
    
    // ViewModel
    class UserViewModel : ViewModel() {
        private val _state = MutableLiveData<UserState>()
        val state: LiveData<UserState> get() = _state
    
        fun processIntent(intent: UserIntent) {
            when (intent) {
                is UserIntent.LoadUser -> loadUser(intent.userId)
            }
        }
    
        private fun loadUser(userId: Int) {
            _state.value = UserState(isLoading = true)
            // 假设 repository 获取用户数据
            repository.getUserById(userId, object : Callback<User> {
                override fun onSuccess(user: User) {
                    _state.value = UserState(user = user)
                }
    
                override fun onError(error: String) {
                    _state.value = UserState(error = error)
                }
            })
        }
    }
    
    // View (Activity)
    class UserActivity : AppCompatActivity() {
        private lateinit var userViewModel: UserViewModel
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_user)
    
            userViewModel = ViewModelProvider(this).get(UserViewModel::class.java)
    
            userViewModel.state.observe(this, Observer { state ->
                // 渲染 UI
                if (state.isLoading) {
                    // 显示加载中
                } else if (state.user != null) {
                    findViewById<TextView>(R.id.userName).text = state.user.name
                } else if (state.error != null) {
                    // 显示错误信息
                }
            })
    
            // 发送 Intent 加载用户数据
            userViewModel.processIntent(UserIntent.LoadUser(1))
        }
    }
    

    MVVM 和 MVI 对比

    MVVM 的优缺点

    优点

    • 简单易理解,易于上手。
    • 更接近传统的 Android 开发模式,使用 Jetpack 组件可以简化开发。
    • ViewModel 与 View 之间通过数据绑定和 LiveData 实现解耦,代码简洁。

    缺点

    • 如果没有严格遵守单向数据流,可能导致状态管理混乱。
    • ViewModel 可能会变得复杂,包含过多逻辑。
    MVI 的优缺点

    优点

    • 强调单一数据流和不可变状态,易于调试和测试。
    • 状态集中管理,UI 只需渲染状态,逻辑清晰。
    • Intent 和 State 的分离,使得代码更加模块化。

    缺点

    • 对于简单的应用可能显得过于复杂。
    • 状态对象可能会变得非常庞大,管理起来比较麻烦。
    • 学习曲线较陡,特别是对不熟悉函数式编程和不可变状态的开发者。
    总结
    • MVVM 更适合大多数传统的 Android 开发场景,特别是中小型项目,简单易用,结合 Jetpack 组件可以提高开发效率。
    • MVI 更适合复杂的应用,特别是需要严格状态管理和单一数据流的项目,尽管初始学习成本较高,但在维护和扩展上具有优势。

    选择哪种架构模式,取决于项目的复杂度、团队的熟悉程度以及具体的需求。综合考虑这些因素,可以做出更适合的架构选择。
    联系我

  • 相关阅读:
    Arduino - 继电器
    利用java语言将csv格式数据导入mysql数据库
    jvm-sandbox demo 菜鸟学习
    基于Python实现的GN算法
    C++17开始取消std::codecvt_utf8支持
    【Python】使用Shell通配符来匹配字符串
    TikTok与心灵成长:娱乐与启发并重
    【笔记】大话设计模式-11-13
    arm-linux gdb远程调试
    是时候使用 YAML 来做配置或数据文件了
  • 原文地址:https://blog.csdn.net/micro9981/article/details/139802006