设计模式只看不练可不行,写个上传解耦库练练手(上)

简介: 写个上传解耦库练练手

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重新传;


  • 上传失败是否需要重试,最多重试次数多少;


  • 上传任务是否还有优先级等;


当然,不要想着一下子就给出完美设计方案,完整的功能实现,受限于设计者的架构经验和有限的排期,先给出一个粗糙的、基础可用的方案,有一个迭代的基础,再慢慢进行优化,最小化可行产品


相关文章
|
6月前
|
设计模式 Java
JAVA设计模式16:职责链模式,轻松解耦发送者和接收者
JAVA设计模式16:职责链模式,轻松解耦发送者和接收者
101 0
|
设计模式
访问者设计模式(Visitor)的生动案例-ASM字节码修改库
访问者设计模式(Visitor)的生动案例-ASM字节码修改库
106 0
|
18天前
|
设计模式 SQL 算法
设计模式了解哪些,模版模式
设计模式了解哪些,模版模式
19 0
|
1月前
|
设计模式 Java uml
C++设计模式之 依赖注入模式探索
C++设计模式之 依赖注入模式探索
37 0
|
3月前
|
设计模式 存储 算法
Java 设计模式最佳实践:三、行为模式
Java 设计模式最佳实践:三、行为模式
22 0
|
2月前
|
设计模式 前端开发 JavaScript
观察者模式 vs 发布-订阅模式:两种设计模式的对决!
欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚开始学习前端的读者们打造的。无论你是初学者还是有一些基础的开发者,我们都会在这里为你提供一个系统而又亲切的学习平台。我们以问答形式更新,为大家呈现精选的前端知识点和最佳实践。通过深入浅出的解释概念,并提供实际案例和练习,让你逐步建立起一个扎实的基础。无论是HTML、CSS、JavaScript还是最新的前端框架和工具,我们都将为你提供丰富的内容和实用技巧,帮助你更好地理解并运用前端开发中的各种技术。
|
14天前
|
设计模式 Java 数据库
小谈设计模式(2)—简单工厂模式
小谈设计模式(2)—简单工厂模式
|
2天前
|
设计模式 存储 JavaScript
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式