MVVM数据单向代码写法
下面的代码中count和_doubleCount是否有有点多余,为什么不直接赋值给count和doubleCount?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class MainViewModel : ViewModel() {
private val _count = MutableLiveData<Int>()
private val _doubleCount = MutableLiveData<Int>()
val count: LiveData<Int> = _count
val doubleCount: LiveData<Int> = _doubleCount
fun incrementCount() {
_count.value = (_count.value ?: 0).plus(1)
}
fun incrementDoubleCount() {
_doubleCount.value = (_doubleCount.value ?: 0).plus(2)
}
}
在Android开发里,这种设计模式是相当常见的,主要目的是保证数据的单向流动以及封装性。
下面来详细分析这样设计的原因:
可变性限制
count
和doubleCount
属于LiveData
类型,这意味着它们是不可变的,外部只能对其进行观察,而无法修改。_count
和_doubleCount
是MutableLiveData
类型,具有可变性,不过被声明为private
,这样就防止了外部对其进行直接修改。
- 数据流向管控
- 采用这种设计,数据的流动方向就被严格限定为只能从ViewModel到View,也就是单向数据流。
- 如果外部可以直接对
count
进行修改,那么数据的流向就会变得混乱,ViewModel将难以对数据的状态进行管理。
安全方面的考量
- 要是直接把
MutableLiveData
暴露出去,就可能会出现 View 层意外修改数据的情况,这是不符合 MVVM 模式设计理念的。
- 要是直接把
下面通过一个例子来说明直接暴露 MutableLiveData
可能引发的问题:
1
2
3
4
5
6
7
8
9
10
11
// 错误示范:不要这样做
class MainViewModel : ViewModel() {
val count = MutableLiveData<Int>() // 直接暴露 MutableLiveData
fun incrementCount() {
count.value = (count.value ?: 0).plus(1)
}
}
// 在Activity中
viewModel.count.value = 100 // 意外地直接修改了LiveData,这违背了数据单向流动原则
总结:这种 private MutableLiveData
搭配 public LiveData
的设计模式,是为了实现数据的单向流动,防止 View 层对数据进行意外修改,从而保证 ViewModel 是唯一能够管理数据状态的地方。
本文由作者按照 CC BY 4.0 进行授权