一、Why Architecture 是重要的
所有架构都有一个共同的目标-管理应用程序的复杂性。在较小的项目中,您可能不必担心它,但是在较大的项目中,它变成了救生员。 Clean Architecture 如何解决这个问题?
简单的说明一下这个图:
Enterprise Business Rules:业务对象
Application Business Rules:用于处理我们的业务对象,业务逻辑所在,也称为Interactor
Interface Adapters: 接口转换,拿到我们需要的数据,表现层(Presenters)和控制层(Controllers)就在这一层
Frameworks and Drivers: 这里是所有具体的实现了:比如:UI,工具类,基础框架等等。
圆圈代表您应用中软件的不同级别。有两件事要注意:
1.中心圆是最抽象的,而外部圆是最具体的。这称为抽象原理。抽象原理指定内部圈子应包含业务逻辑,外部圈子应包含实现细节。
2.干净架构的另一个原则是依赖规则。该规则指定每个圆只能依赖于最近的向内圆-这就是使体系结构起作用的原因。
外圈代表特定于平台的具体机制,例如网络和数据库访问。向内移动,每个圆圈都更加抽象和更高层次。中心圈是最抽象的,包含业务逻辑,它不依赖您使用的平台或框架。
在构建应用程序代码时使用体系结构的其他好处包括:部分代码解耦,更易于重用和测试。有一种疯狂的方法。当其他人使用您的代码时,他们可以学习该应用程序的体系结构并会更好地理解它。
Clean Architecture 层级
一般的分类是五层:
这里已Google的 MVVM架构 architecture-samples-usecases 为例子
比基本的MVVM架构其中添加了一层新的Domain Layer层。其包装都是通过一个个UseCase来完成V层和M层的交互的。
我们看看基础的文件目录的不同,其添加了一个domain的一个目录,里面有多个usecase的类,用于对Task的操作。
addedittask:这个目录可以看成是Presentation层。用于UI相关的交互。
data:这个目录可以看成Model层。Task类是保存的基本的任务信息类,都是以Task基本对象来传递任务。
其中的TasksDataSource、TasksRepository两个接口很重要,前面说到的内层不能持有外侧,那么这个怎么交互呢就靠这个接口。各个UseCase中间的交互调用接口。
而local中则是最外侧的实现接口的部分。
domain:这里封装了各个业务逻辑的UseCase。可能这个UseCase的概念需要理一理,举例说上面的一个删除任务的业务逻辑就封装成一个UseCase。 Domain层的大部分业务逻辑都是在Use Case中实现的。这里是一个纯java模块,不包含任何的Android依赖
基本分析一下UseCase :
class DeleteTaskUseCase(
private val tasksRepository: TasksRepository
) {
suspend operator fun invoke(taskId: String) {
wrapEspressoIdlingResource {
return tasksRepository.deleteTask(taskId)
}
}
}
这里再看一下ViewModel中的调用关系,这里调用之后得到返回值,再把事件给相关的LiveData.在TaskDetailFragment中监听相关的事件变化,从而完成整个的事件的处理。
fun deleteTask() = viewModelScope.launch {
taskId?.let {
deleteTaskUseCase(it)
_deleteTaskEvent.value = Event(Unit)
}
}
到这里流程已经讲了一遍,如果不清楚流程可以研究一下,一开始的时序图。
高内聚和低耦合侧重于理解了。但是易于维护,这样的结构已经能说明了,易于测试也好理解,各个模块独立,来看看这: