17. 一个结构较为合理的下载模块该怎么设计

作者: halohily

最近负责下载组件的开发,对于如何设计一个下载模块有一些粗浅体会,今天分享一下我采用的方案,希望能够抛砖引玉。另外,最近会出两篇主题为“下载组件的设计”和“与 Hybrid 相关的下载方案”的长文,欢迎关注 「 知识小集 」公众号。

“下载”作为一个需要本地结构化、持久化存储的场景,使用数据库是比较自然的选择。所以,我们首先拆分出一个数据库模块,用来存储下载记录。主要字段为下载任务的信息,如 url、文件大小、时间戳等,以及最重要的文件本地存储路径。这一层可以在接口设计上认真思虑,比如仅涉及当前业务逻辑,而不涉及具体的数据库操作,相当于是较 FMDB 等数据库组件来说更高层的抽象。后期需要更换底层数据库引擎时,本层封装无需改动,是比较理想的实现。

数据库是用来存储下载记录的,那么所下载的具体文件呢?自然就需要一个文件管理模块,在这个模块里,负责根据文件 url 生成本地的存储路径,以及进行文件校验、存储、移除等操作。

所要下载的文件,我们可以按体积、类型等进行区分。对于网络请求的结果这类简短内容,我抽象出了一个缓存管理器,用来完成网络请求、图片等内容的缓存。网络请求的 JSON 格式结果,可以选择 YYCacheEGOCache 等缓存框架。而图片的缓存,则可以选择专注图片缓存的 YYWebImageSDWebImage 等框架。

对于体积较大的文件,自然需要一个专注大文件下载的模块。这个模块不关注具体的文件类型,不关注具体的业务场景,它只需要文件 url 、文件管理模块生成的本地目标路径,完成下载任务即可。

在以上通用模块的基础上,有一个业务层的封装,它负责根据提交的下载任务,协调调用各基础组件。举个例子,一个下载任务包括一个视频文件、一个网络请求结果、三张图片。本模块在收到任务后,首先解析出以上的任务具体结构。使用文件管理模块,根据视频文件 url 生成本地存储目标路径,调用大文件下载器完成下载,此为一个子任务。对于网络请求结果,调用缓存模块,进行缓存,此为一个子任务。对于三张图片,使用图片缓存器完成缓存,此为一个子任务。三个子任务均完成,使用数据库模块,对下载记录、媒体文件记录等进行存储。除此之外,本模块还负责对外提供下载中任务、已下载任务等数据。

Last updated