【尚未完成】【Android架构底层逻辑拆解】Google官方项目NowInAndroid研究(4)数据层的设计和实现之data

闻过则喜,知过不讳,改过不惮。

这是NIA系列文章中,数据层部分的最后一篇。在这篇博客中我将首先从宏观角度纵览数据的分层设计思路,随后分析数据仓库层:core:data的实现。

数据的分层设计

采用自底向上顺序,将整个NIA项目的数据层拆分如下表。

层次 说明 对上层暴露接口
数据源Source 数据的存储方式,如服务器、数据库、文件 单例,NetworkDataSource(服务器)、XXXDao(数据库),以Bean作为函数返回
数据仓库Repository 封装底层具体存取实现,通常会组合2~3个底层接口对象 单例,XXXRepository,以Flow对象作为函数返回
领域Domain 拆分后的业务基本能力,类似"数据中台" XXXUseCase,供ViewModel使用,以Flow对象作为函数返回值
特性Feature 对应到页面粒度的ViewModel 向上传递数据,向下传递控制

按照package拆分

  • di: 通过依赖注入生成各个Repository的单例
  • model: network层的数据对象,同样会将其转换为通用的Topic、NewsResource等来使用
  • repository: 依照业务实体划分的各个Repository,对外(上层业务)暴露的主要接口,返回的数据格式为Flow
  • util: 请求监控、数据同步等工具类

di------依赖注入绑定默认的Repository

di包内部有两个类,分别是生成UserNewsResourceRepositoryinterface UserNewsResourceRepositoryModule和生成TopicsRepositoryNewsResourceRepository等的abstrace class DataModule

疑问:同样是借助Hilt注入能力自动生成单例对象,为什么使用了接口、抽象类两种不同的写法?是否可以只采用接口来实现?

是否可以只采用接口来实现?------在当前项目的场景中,这个问题的答案是肯定的。首先来学习了解下这两种方式的区别。

知识点:Hilt的两种注入方法

Hilt框架提供了抽象类、接口两种注入方式,这两种注入方式的区别其实也就是抽象类、接口之间的区别,比如抽象类可以含有属性及非抽象函数等。

特性 抽象类写法 接口写法
类类型 必须声明为 abstract class 必须声明为 interface
方法修饰符 需显式添加 abstract 关键字 方法默认抽象,无需 abstract 关键字
构造函数 可以有构造函数(但 Hilt 模块不需要) 不能有构造函数
成员变量 可声明非静态属性 不能有属性(仅支持抽象方法)
多继承 单继承(Kotlin 单继承限制) 支持多实现多个接口
代码风格 更贴近传统 Java 风格 更符合 Kotlin 简洁风格

在具体代码中,这两种写法有些微的不同。

kotlin 复制代码
// 抽象类写法(必须显式声明 abstract)
@Module
abstract class DataModule {
    @Binds
    abstract fun bindsRepo(impl: Impl): Interface
}

// 接口写法(默认抽象,无需关键字)
@Module
interface UserRepoModule {
    @Binds
    fun bindsRepo(impl: Impl): Interface // 隐式抽象
}

如果需要结合@Binds@Provides,则只能使用抽象类,因为后者依赖于完整的函数实现。

kotlin 复制代码
@Module
abstract class HybridModule {
    @Binds
    abstract fun bindInterface(impl: Impl): Interface

    @Provides
    fun provideUtility(): Utility {  // 接口无法添加此方法
        return Utility()
    }
}

如果不需要@Provides,那么使用抽象类和接口是等价的,两种写法最终都会被 Hilt 处理为相同的依赖注入逻辑,没有性能或功能上的差异。出于接口契约性编码简洁 的考虑,最佳编程实践是使用接口Interface

Repository------封装后的数据仓库

repository包内部大部分都是以XXXRepository命名的类,

Sync同步机制

相关推荐
zhuyasen1 小时前
定义即代码!这个框架解决了90%的Go开发者还在低效开发项目的问题
架构·go·gin
LCG元1 小时前
云原生微服务间的异步消息通信:最终一致性与系统容错的架构实战
微服务·云原生·架构
骑着王八撵玉兔2 小时前
【性能优化与架构调优(二)】高性能数据库设计与优化
数据库·性能优化·架构
Jiude3 小时前
MinIO 社区版被故意阉割,Web管理功能全面移除。我来试试国产RustFS
后端·docker·架构
西陵5 小时前
Nx带来极致的前端开发体验——借助CDD&TDD开发提效
前端·javascript·架构
文火冰糖的硅基工坊9 小时前
[创业之路-458]:企业经营层 - 蓝海战略 - 重构价值曲线、整合产业要素、创造新需求
科技·重构·架构·创业·业务
小张是铁粉10 小时前
oracle的内存架构学习
数据库·学习·oracle·架构
小马爱打代码15 小时前
微服务外联Feign调用:第三方API调用的负载均衡与容灾实战
微服务·架构·负载均衡
9527华安19 小时前
FPGA实现40G网卡NIC,基于PCIE4C+40G/50G Ethernet subsystem架构,提供工程源码和技术支持
fpga开发·架构·网卡·ethernet·nic·40g·pcie4c
guojl1 天前
深度解决大文件上传难题
架构