MVVM设计架构浅析
实习时用的是MVP架构,但Google官方本身已经将MVVM(Model-View-ViewModel)MV作为推荐的设计架构,在JetPack当中也推出了一系列组件来支持,简单谈一下我对MVVM的理解
MVVM架构特点
- 分离关注点:MVVM 将用户界面的表示(View)与业务逻辑和数据(ViewModel)分离开来,使得代码结构清晰,易于维护和扩展。ViewModel 作为连接 View 和 Model 的中间层,负责处理用户交互和数据绑定。
- 双向数据绑定:MVVM 支持双向数据绑定,使得 View 和 ViewModel 之间的数据同步变得简单。当 ViewModel 中的数据发生变化时,自动更新关联的 View,反之亦然。这样可以避免手动更新界面的繁琐操作,提高开发效率。
- 响应式编程:MVVM 借助观察者模式和数据绑定,实现了响应式编程的特性。ViewModel 中的数据变化会触发相应的事件或通知,从而更新关联的 View。这种机制使得界面的状态和数据保持同步,并支持实时更新。
- 可测试性:由于 MVVM 将业务逻辑从 View 中分离出来,使得 ViewModel 可以独立于界面进行单元测试。通过模拟输入和验证输出,可以方便地对 ViewModel 进行单元测试,保证代码质量和功能正确性。
- 可重用性:MVVM 鼓励将界面逻辑与数据逻辑解耦,使得 ViewModel 可以在不同的界面中重复使用。这种可重用性降低了代码的重复编写,提高了开发效率。
总的来说,MVVM 提供了一种结构清晰、可测试、可重用的开发模式,使得开发者可以更好地管理和组织代码,提高开发效率,并改善用户界面的交互和体验。
带来的改变
结合上述特点,说一下我理解的MVVM为Android应用开发带来的改变:
- 分离关注点:分离关注点的设计可以减少代码的耦合性,使得开发者可以专注于不同层级的逻辑,提高代码的可读性和可维护性。
- 可测试性:由于 ViewModel 是纯逻辑的组件,可以通过模拟输入和验证输出来进行单元测试,验证其功能的正确性。这样可以提高代码质量,降低 bug 出现的概率。
- 数据驱动的界面更新:MVVM 采用双向数据绑定机制,实现了数据驱动的界面更新。ViewModel 中的数据变化会自动更新关联的 View,而用户界面上的输入变化也会实时反映到 ViewModel 的数据中。这种机制使得界面的状态和数据保持同步,减少了手动处理界面更新的代码,提高了开发效率。
- 解决横竖屏切换问题:MVVM 架构中,ViewModel 负责保存和管理界面的数据状态。在横竖屏切换时,Activity 或 Fragment 可以销毁并重新创建,而 ViewModel 可以保持不变,从而避免了数据的丢失和重复加载。这种方式使得横竖屏切换更加流畅,用户无感知。
- 提升代码的可重用性:由于 MVVM 架构将界面逻辑与数据逻辑解耦,使得 ViewModel 可以在不同的界面中重复使用。这种可重用性降低了代码的重复编写,提高了开发效率。
总体而言,采用 MVVM 架构模式可以改善 Android 开发中的代码组织、可维护性、可测试性和用户界面的交互体验,使得开发者能够更好地管理和开发 Android 应用。
典型MVVM样例
在典型的 Android MVVM 架构中,可能包含以下几个关键类:
- Model(模型):Model 类表示应用程序的数据模型,通常是实体类或数据访问层。它负责封装数据和提供数据操作的方法,如从数据库或网络获取数据。
- View(视图):View 类表示用户界面的可视化部分,通常是 Activity、Fragment 或自定义视图。它负责展示数据、接收用户输入和处理用户界面事件。
- ViewModel(视图模型):ViewModel 类是连接 View 和 Model 的中间层。它持有与用户界面相关的数据,并提供方法供 View 层触发业务逻辑和数据操作。ViewModel 通常包含 LiveData 或 RxJava Observables,用于处理数据变化和实现双向数据绑定。
- Repository(仓库):Repository 类用于封装数据源的访问逻辑。它可以从本地数据库、网络或其他数据源获取数据,并将数据提供给 ViewModel 层。Repository 的存在可以解耦 ViewModel 层和底层数据源的具体实现。
- LiveData(生命周期感知的数据持有者):LiveData 是 Android 架构组件之一,用于在应用程序组件之间进行数据通信。它是一种观察者模式的实现,可以感知生命周期,并确保数据的更新仅在活跃状态下进行。
- Data Binding(数据绑定):Data Binding 是 Android 的特性之一,用于在布局文件中直接绑定数据到 View。它通过生成绑定类,将视图和 ViewModel 之间的数据绑定自动化。
这些类是 MVVM 架构的核心组件,每个类负责不同的职责,共同协作实现数据的管理、展示和交互。然而,具体的实现方式可能因开发者和项目需求而有所不同。
下面展示一个简单登录页面的示例代码:
activity_login.xml(布局文件):
1 | <layout xmlns:android="http://schemas.android.com/apk/res/android"> |
LoginViewModel.kt(ViewModel):
1 | class LoginViewModel : ViewModel() { |
LoginActivity.kt(Activity):
1 | class LoginActivity : AppCompatActivity() { |
在上述代码示例中,布局文件 activity_login.xml 使用了数据绑定,其中的 EditText 和 Button 的文本属性与 ViewModel 的 username 和 password 属性进行双向绑定。ViewModel 类 LoginViewModel 包含了处理登录逻辑的方法和 MutableLiveData 对象用于保存输入的用户名和密码。Activity 类 LoginActivity 在 onCreate() 方法中使用数据绑定设置 ViewModel 和生命周期所有者。
ViewModel的职责
在 MVVM 架构中,业务逻辑通常会放在 ViewModel 类中。ViewModel 作为 View 和 Model 之间的中间层,负责处理用户界面的交互和数据操作。
具体来说,ViewModel 类可以包含以下业务逻辑:
- 用户交互处理:ViewModel 可以响应用户的交互操作,例如按钮点击、列表项选择等。当用户与界面进行交互时,ViewModel 可以执行相应的业务逻辑,如验证输入、发起网络请求、处理数据等。
- 数据转换和格式化:ViewModel 可以负责将 Model 中的原始数据进行转换和格式化,以满足界面的显示需求。例如,将日期数据转换为特定格式、将数值进行格式化等。
- 数据持久化:如果需要将数据保存到本地存储(如数据库),ViewModel 可以负责处理数据的读取和写入操作。它可以与 Repository 层协同工作,从数据源获取数据或将数据存储到数据源中。
- 状态管理:ViewModel 可以管理界面的状态,如加载中、错误状态、空数据状态等。它可以维护相关的状态变量,并根据业务逻辑的执行情况更新状态,以便在界面上正确显示相应的状态。
将业务逻辑放在 ViewModel 中有助于将用户界面和业务逻辑分离,使得代码结构更清晰、易于维护,并提供可测试性。同时,View 层只需要关注界面的展示和用户交互,而不需要直接操作数据和执行复杂的业务逻辑。
此外,ViewModel 应该遵循单一职责原则,不应该包含过多的业务逻辑。如果某些业务逻辑比较复杂或耗时,可以考虑将其委托给其他类或使用异步操作。