我的Android项目架构进化论(三)

2,433 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情

前言

上一篇我们了解了MVP业务架构在项目中的使用,这一篇我们来了解一下MVVM业务架构。MVVM是我目前为止使用时间最长的一个业务架构,从开始的EventBus实现View层和逻辑层的解耦到后来的我们自己封装的观察者,再到现在的ViewModel实现解耦。这一篇我们重点说一下ViewModel的实现方式,它不是最好的,也不是独一无二的,它有缺点也有借鉴而来的,但它却是我们项目截止目前最合适的。

在这套架构出来之前我们在旧项目上实现过MVVM,那时是采用广播的思想进行实现的,后来发现这种实现方式弊端众多,像如何有效维护事件,如何避免内容泄漏等等。直到19年新起项目的时候我们决定重新设计一套合适的架构,设计之初jetpack刚发布没多久,好多库都还是Alpha版本。一开始我还挺担心jitpack会夭折,毕竟谷歌也不是没有干过这种事,在团队成员沟通交流后我们确定了jitpack作为新项目的技术基点。

概览

MVVM作为MVP演变而来的业务架构,从业务实现来说将原有Presenter层所实现的逻辑放到了ViewModel层,同样根据MVP的情况我们不难看出业务臃肿转移到了ViewModel层,那又是如何来解决的呢?

职能

类型职能
M-Model模型层,主要用于数据的处理及存储,像网络请求和本地存储数据请求及处理等。
V-View视图层,主要用于UI样式的呈现及处理,像xml布局和Activity中的控件及其展示效果等。
VM-ViewModel逻辑层,主要用于承载View层和Model层交互处理以及数据通信,像数据模型业务等。

技术点

  1. Lifecycle:生命周期感知组件,通过可执行操作来响应另外一个组件。
  2. ViewModel:以生命周期的方式存储和管理界面相关的数据。
  3. LiveData:可观察的数据存储器类,仅更新处于活跃的生命周期状态的应用组件观察者。
  4. Coroutine:协程是提供编写异步代码的API,减少线程的开心。
  5. Room:本地数据存储,持久性库在 SQLite 上提供了一个抽象层。
  6. Hilt:依赖注入,将对象的初始化所需的依赖项通过抓取的形式注入。(替换Dagger时加入的)
  7. Flow:异步流,让业务像溪流一样链接起来。(这是后来加入的)

业务架构分层

层级职能
View层视图层,视图渲染层,如xml,webview,flutter,compose等
ViewModel层视图控制层,视图渲染条件业务。如展示内容数据容器,视图数据校验等
Repository层数据仓库层,数据业务数据处理。如视图内容组装,网络参数组装等
Source层数据源层,业务数据获取层。如网络请求,本地数据库查询等

mvvm业务架构图.png

View层

定位是实现业务视图呈现的相关逻辑,像xml的click事件,recyclerview数据渲染等等。还是用activity或者fragment作为视图容器,xml的控件绑定采用的是viewbind。当前view层主动持有一个ViewModel的实例。

ViewModel层

定位是实现视图控制的相关逻辑,像click响应什么样的事件,视图是否允许展示dialog等等。主要是继承ViewModel类,提供给View层可观察的LiveData数据,也是flow异步流发起和收集的地方。当前ViewModel层主动持有一个Repository层的实例。

Repository层

定位是实现为ViewModel层提供可展示的数据,像recyclerview应该展示那些数据,这一层主要是用作数据组装,一个视图数据的展示可能来自不同的数据源,这时我们可以组装为一个可直接供视图展示的数据结构,从而减小ViewModel的数据处理压力,ViewModel只需要专注控制View层的逻辑即可。当前Repository层主动持有多个Source层实例。

Source层

定位是为业务提供数据源,这是与业务无关的一层,他只与Model层相关系,它通过向Model层索要数据,无论数据的来源是server还是room,它只对外提供数据源,不关心下游的使用方式。可以说他是Model层向上引申的一层定义,旨在提供某一类数据源。

结语

这一篇我们大概了解了当前项目对于MVVM的定位,以上的定义语言可能不能准确的表达它的定位。下一篇我们将通过具体的实例来进一步阐述这套业务架构。