前言
Android真响应式架构系列文章:
之前我介绍了Airbnb的响应式架构MvRx,以及它界面响应式的关键——Epoxy。从这篇文章开始,我会写几篇文章来介绍一下,我应用MvRx的一些实践。
这篇文章是关于Model层设计的,对,就是MVC、MVP、MVVM中的那个Model。其实,Model层的设计和响应式架构没有关系。但是,因为这是一系列的文章,为了统一,我还是这么命名了。
本篇介绍的Model层设计与响应式架构无关,别的架构同样可以参考这样的设计。
本文介绍的一切都基于一点:数据流的设计,即以RxJava的方式包装Model层的数据,然后进行合理的数据分层,以实现对数据流的分层管控。因此,希望你熟悉RxJava。
1. Model层的分层
优秀的架构离不开合理的分层设计,我们经常说的MVC、MVP、MVVM正是从大的方面描述了整体架构的分层模式。然而,仅仅在大的方面做好分层还是远远不够的,每一层本身也可能是非常复杂的,在每一层内部还要进行细分。因此,我们需要对Model层进行进一步的细分设计。
1.1 网络层的分层设计
相信大家对于网络层采用Retrofit+RxJava的方案应该没有什么异议,甚至Retorfit都不必强求,只要网络层的数据是以RxJava数据流的形式提供的即可。不过,下面我仍然会使用Retrofit来举例。
1.1.1 数据过滤层
如果网络层的数据不是“纯净”的,我们第一步应该做的事情是去除“噪声”。假设后台的数据都是以如下的JSON形式返回给我们的:
{
"status": 200,
"data": "我是String"
}
{
"status": 200,
"data": {
//我是JSONObject
}
}
{
"status": 200,
"data": [
//我是JSONArray
]
}
以上这种接口设计还是很常见的,我们真正需要的数据保存在data字段中,所以我们这里设计一个数据过滤层,拿到我们真正关心的数据,然后再做别的处理。
/**
* 网络返回的数据
*/
class StatusData(
val status: Int = 0,
val data: T
)
/**
* Retrofit接口
*/
interface UserApi {
/**
* 获取用户信息
*/
@GET
fun getUserInfo(): Observable>
/**
* 常见问题
*/
@GET
fun faq(): Observable>>
/**
* 清空消息
*/
@DELETE
fun clearNotices(): Observable>
}
/**
* 数据过滤层
*/
interface UserService {
fun getUserInfo(): Observable
fun faq(): Observable>
fun clearNotices(): Observable
}
/**
* 对网络请求返回的数据类型进行转换,StatusData -> T
*/
inline fun unwrapData() = Function, T> {
it.data as T
}
/**
* 真正的网络请求实现类
*/
@Singleton
class UserClient @Inject constructor(
private val userApi: UserApi
) : UserService {
override fun getUserInfo(): Observable =
userApi.getUserInfo().map(unwrapData())
override fun faq(): Observable> =
userApi.faq().map(unwrapData())
override fun clearNotices(): Observable =
userApi.clearNotices().map(unwrapData())
}
首先定义网络数据的泛型表示类StatusData,还有Retrofit网络请求接口UserApi,然后定义一个数据过滤层UserService,主要作用是将StatusData转换为T,只保留我们真正关心的数据(无论数据是String,还是数据类,抑或是List),最后,在UserClient中实现UserService接口,实现真正的网络请求。
1.1.2 数据过滤层->数据中间层
如果只是为了过滤“噪声”的话