Android开发者重读设计模式:写个上传解耦库练练手

本文作者在阅读完设计模式之美后,决定重构公司的Android上传库作为练手项目。文章探讨了为何需要重构上传库,提出了不重构的低成本方案,并详细拆解了重构过程中的需求,设计了基于责任链的架构。此外,作者还介绍了如何自定义Task、上传配置、拦截器,以及库的初始化和使用方法,通过Demo展示了上传库的实际效果。
摘要由CSDN通过智能技术生成

上周总算是把设计模式之美看完了,一直想写个东西练练手,碰巧最近要重构公司的上传库,所以有了这篇文章。(仅仅是学习练手,有建议可以提,架构大佬轻喷)

0x1、杂谈

① 为什么要重构上传库?

我司APP在上传图片/视频前,需要进行一系列处理,最后才上传,如:

  • 图片:判断路径是否存在 → 通过Exif信息判断是否需要旋转 → 判断是否需要压缩 → 获取MD5 → 如果开启秒传查询是否有秒传记录,有直接返回 → 没有才上传 → 上传完成对应状态更新;
  • 视频:判断路径是否存在 → 判断是否需要压缩 → 要压缩的话压缩 → 获取MD5 → 获取视频第一帧 → 判断是否需要压缩 → 要压缩的话再获取一次视频MD5 → 同样是秒传验证 → 上传完视频传第一帧图片

有些业务场景的处理更复杂,Talk is cheap,show you the code,出现这样的代码很正常(局部):

得益于rx链式调用,上述代码是已经简化后的一版了,可以想象没rx前的就更混乱了,对写的人来说负担,对看的人来说也是,重构势在必行...

② 不重构的话有其他低成本一点的方案没?

答:,在上面代码的基础上优化,把flatMap抽取为单独的功能函数,按流程调用,当然,也不算太优雅。最优雅的应该是上Kotlin协程,写几个挂起函数,同步方式写异步代码。当然,问题也有:一丢丢的学习成本 和 不能在Java里用。

0x2、需求拆解

原始需求

写个图片上传库,给你一个本地图片路径、一个上传接口,完成图片上传。

小白视角

简单,库都不用谢,直接写个UploadPicUtils工具类,定义一个上传方法就好了

光速敲完代码:

object UploadPicUtils {
    fun uploadPic(picPath: String, serverUrl: String) {
        val pic = File(picPath)
        if(pic.exists()) {
            // 执行网络上传操作(如调用OkHttp直接传)
            // 利用rx或EventBus通知上传结果,给出成功、失败反馈
        }
    }
}
// 上传图片处调用:
UploadPicUtil.uploadPic("本地图片路径", "上传接口")

看着挺简单的,但 唯一不变的是变化,需求往往是反复无常的~

  • 因为公司不舍得买图片加水印服务,所以客户端传图片前本地要加下水印;
  • BUG:有用户用自己手机拍照,上传后的图片却旋转了,上传前要检查下,歪了的要摆正;
  • BUG:有用户反馈上传图片太慢,一排查图片太大,服务器顶不住,上传前要做下图片压缩;
  • 某些图片尺寸有规定(X*Y),尺寸不对的不能上传;
  • 秒传功能,md5一样的文件传过就不要传了,直接返回地址;
  • 支持同时上传多张图片;
  • 现在不止传图片了,还有传视频、音频、文件、文件夹等场景...

然后代码就变成上面这样的结果,写的人看了沉默,接盘的人看了流泪。

所以,在拿到原始需求时,不要上来就肝代码,而是 对需求进行拆解、分析、假设和思考

  • 真的只上传图片吗?后面会不会要传其他东西,如音视频?
  • 要做图片有效性校验吗?如:存不存在,大小是否为0,文件格式为图片类型等;
  • 库需要对上传图片做什么特别的处理吗?如打水印、翻转、压缩、切割、尺寸校验等;
  • 是否要支持多张图片同时上传,最多多少张同时传;
  • 是否要支持秒传;
  • 不同手机系统版本或设备文件获取API兼容;
  • 上传接口地址是不是一直变化的,是否需要鉴权,是否有特定上传配置;
  • 上传任务在后台异步进行,还是前台同步堵塞,上传中途能否取消;
  • 上传任务中断了(杀掉APP)是否需要保留进度,下次打开APP重新传;
  • 上传失败是否需要重试,最多重试次数多少;
  • 上传任务是否还有优先级等;

当然,不要想着一下子就给出完美设计方案,完整的功能实现,受限于设计者的

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值