【尚未完成】【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同步机制

相关推荐
MZWeiei11 小时前
Spark SQL 运行架构详解(专业解释+番茄炒蛋例子解读)
大数据·分布式·sql·架构·spark
#金毛11 小时前
一、HAL库的设计理念详解:从架构到实践
stm32·嵌入式硬件·架构
是麟渊11 小时前
【大模型面试每日一题】Day 17:解释MoE(Mixture of Experts)架构如何实现模型稀疏性,并分析其训练难点
人工智能·自然语言处理·面试·职场和发展·架构
好吃的肘子12 小时前
MongoDB 高可用复制集架构
数据库·mongodb·架构
TsingtaoAI12 小时前
医疗系统开发架构和技术路线建议-湖南某三甲医院
架构·医疗ai系统·医疗信息化·医疗系统架构·医疗ai机构
敲代码的 蜡笔小新12 小时前
【行为型之命令模式】游戏开发实战——Unity可撤销系统与高级输入管理的架构秘钥
unity·设计模式·架构·命令模式
码上飞扬13 小时前
MongoDB数据库深度解析:架构、特性与应用场景
数据库·mongodb·架构
九章云极AladdinEdu15 小时前
GPU SIMT架构的极限压榨:PTX汇编指令级并行优化实践
汇编·人工智能·pytorch·python·深度学习·架构·gpu算力
blues_C15 小时前
【专栏启动】开篇:为什么是 Django + Vue3?测试平台的技术选型与架构蓝图
架构·django·测试平台
胡斌附体16 小时前
微服务调试问题总结
java·微服务·架构·调试·本地·夸微服务联调