原文地址:Android-Desmitificando Clean Architecture
作者:Armando Picón
在谈论 Clear Architecture 架构之前,我们应该先了解一下它的背景:
- Clean Architecture 是 Robert C. Martin 写的一本书的标题。
- 它不是一种独立的体系结构,而是一套要遵循的原则指导。
- 这套原则指导的基础在于应用 SOLID 原则。
- 总得来说,它试图将应用的结构建立在以 Domain 层(应用程序的逻辑实现层)为核心的基础上。
- 很多开发人员将用 N 层架构来混淆它。
- Clean Architecture 不是解决所有问题的灵丹妙药,它只是一种流行的表达方式,适用于开发人员描述项目结构的简易方式。
什么是 Architecture
简单来说,它是一个结构,是将应用中的组件分到不同组合中的方式。因此,并不存在一种独一无二的组织项目的方式。诸如项目的状态、团队的规模、时间等多方面因素会影响你在组织应用程序组件方面所做的决定。
在 Android 中的 Clean Architecture
很多关于如何在我们开发的应用程序中应用 Clean Architecture 的文章已经被讨论和举例过了,许多开发人员将谈论关注点分离和测试作为遵循这些原则的主要特点,但有关 Clean Architecture 的一个非常重要的方面往往被忽略,即其基础在于实现 Domain 层。
了解了这一点,那么按照这些原则如何构建一个基础项目呢?在处理此问题时,有两个重要的考虑因素:
- Clean Architecture 中有一个规则,即外层层级将依赖于内层层级,而非相反,最终 Domain 层不依赖任何层。
- 有一个数据流通过所有外部和内部层,从用户输入数据(或传感器输入数据)开始向前传递,通过业务/应用逻辑,最终到数据的持久性或将数据发送到远程服务,并且从服务操作结果返回给用户展示。
考虑到这两个方面,一个基本结构将包括三个模块:presentation
、domain
、data
。它们之间的关系将如下:
每一层会包含哪些组件呢?
重要的是要强调,在谈论架构时,我们谈论的是组织和架构,因此每个模块中特定的组件的分布以及放置取决于你选择采用的模式以及每个模块的目的。
- Domain 层:Domain 层包含应用程序的逻辑和业务逻辑。这些 Domain 测过通常包括 Domain 类以及负责业务逻辑的组件,如用例或交换器。这个模块不应该依赖于 Android 框架或第三方依赖库,通常是一个 Kotlin 模块。
- Presentation 层:Presentation 层包含展示信息给用户、接收用户数据或传感器信息的元素。在这个模块中会包括 Android 特有的视图组件(Activity 和 Fragment)、UI 系统(XML 文件或 Compose 函数),以及根据相应的设计模式(如 MVP 或 MVVM)可能包括 Presneter 或 ViewModel。这个模块是一个 Android 模块。
- Data 层:Data 层包含网络请求库(如 Retrofit、Volley 等)和数据存储(如 Room、SharePreferences、DataStore、Firebase 等)的依赖项。如果使用 Repository Pattern 模式,在这一层将包括仓库的实现和数据源(data source)。这个模块同样是一个 Android 模块。
当然,你可能会产生一下疑问:如果 Domain 没有访问 Data 层,那么我们如何在用例中注入仓库呢?答案可以在 SOLID 原则中的依赖反转原则(Dependency Inversion Principle)找到。
Dependency Inversion Principle
这个 SOLID 原则包含两个要点:
- 高级模块不易昂改依赖第一模块。但是两者应该依赖于接口。
- 抽象不应该依赖于细节。细节应该依赖于抽象。
有了这个原则,我们的 Domain 模块将拥有在数据模块内部实现的仓库接口。
在代码中,我讲大致如下所示,在 Domain 模块中会有一个BookRepository
的接口:
kotlin
interface BookRepository {
suspend fun getBooks(): List<Book>
}
class GetBooksUseCase(
privat val bookRepository: BookRepository
) { /*...*/}
在 Data 模块中将包含其具体实现。
kotlin
class BookRepositoryImpl (...) : BookRepository {
override suspend fun getBooks(): List<Book> { /* ... */ }
}
因此,在创建我们的实例时,我们可以注入实现,这是由于我们声明的接口。
结论
在结论部分,可以提到以下几点:
- 拥有一种组织组件的架构方式要比没有更好。
- Clean Architecture 并不是一种独立的架构,但它为我们提供了一个遵循的指南,以便我们结构化我们的项目。
- 还有其他一些架构并没有那么出名,但它们同样非常实用。
- 有了这种结构,你可以自由选择不同的展示方式(无论是 View、 XML还是 Compose)以及数据访问层(如 Retrofilt、Room、SharePreferences 等)
- 在我的经验中,良好地应用 SOLID 原则为你的架构打下良好的基础。
- Android 官方推出的新架构指南并没有遵循 Clean Architecture,但提供了一个分层的架构。
下一篇文章将讲解 Android 官方推出的新架构~