继上篇《Flutter 下载篇 - 壹 | flutter_download_manager源码解析》中详细介绍了flutter_download_manager用法和原理。在优缺点中提到,该库纯Dart实现,支持下载管理,暂停,恢复,取消和断点续传。其中有个缺点是网络库与dio强耦合,不支持自定义网络库扩展。
有人会说: dio这么牛逼,直接用不就好了,为啥还要支持别的网络库,没事别瞎折腾。
我想说:
本文将从现状出发,一步步带你解耦flutter_download_manager中的网络库。
从类图上整体了解flutter_download_manager类设计过程中对dio强耦合概括,然后通过代码具体讲解。
每个下载任务请求中都会使用到dio:CancelToken 通过dio网络库间接实现任务的取消功能。
cancelToken.cancel() 算依赖CancelToken
如上简写代码中调用链关系,最终调用链及对dio依赖关系总结:
下载库对dio的依赖在于: CancelToken和download方法。
通过上述对现状分析总结,结合设计基本原则:封装变化将不变从变化中隔离出来。其中变化的就是网络库的下载,CancelToken和取消功能。只用封装这部分变化,将网络库下载和Token抽象出来进行封装。
目的:让flutter_download_manager与dio.download解耦。
思路:将网络相关操作抽象成接口,依赖注入到downloadManager对象中。
实施步骤:
考虑到download返回Future中对象问题,因为会用到response.statusCode,这里直接用dynamic来,具体可以细化成封装成DownloadResponse,其中包含statusCode属性。
目的:让flutter_download_manager与dio.CancelToken解耦。
思路:CancelToken与取消息息相关,而且必须提供一个cancel方法来供downloadmanager中暂停等方法使用。考虑到每个custom_http_client的CancelToken结构体存在不一样,而cancel方法命名多样性原则,这里设计一个统一的DownloadCancelToken接口,提供cancel方法,将其中实现代理给具体网络库的CancelToken对象。
实施步骤:
小技巧: 用Function.apply是因为它本身支持位置参数和可选参数传入。
目的:下载器与具体实现downloadmanager解耦
思路:downloadmanager中提供了addDownload等下载通用方法及下载管理逻辑抽象。这块存在变化可以有多种实现,也抽象下。
实施步骤:
至此,可定制网络库改造已全部完成,接下来就可以隔离dio网络实现了。
通过依赖注入到DownloadManager中即可。
如此就完成了对flutter_download_manager的网络库扩展改造,实现了一个可定制化的网络框架的下载库。
做开闭原则前,最重要的是以最小实现模型为基础捋清楚代码中的变与不变。
太棒了!鼓励自己坚持到底。我希望我为你投入的时间增加了一些价值。
本文原创听蝉。