将实例的构建和使用分隔开,降低代码耦合度,可以实现对象的灵活配置 , 封装对象的创建逻辑,简化对象的使用,提供对象的复用和管理,说了这么多,我们来看下Glide怎么用的。

  • 简单工厂

glide 通过工厂构建不同类型的线程池,很好理解。

  • 工厂方法

每一个具体实例对应一个具体工厂

例子:用来感知网络连接状态的接口ConnectivityMonitorFactory和 ConnectivityMonitor,和高层RequestManager。

ConnectivityMonitorFactory在Glide 初始化被构建,因为ConnectivityMonitorFactory生产的ConnectivityMonitor构建需要依赖 android 中的Context 上下文,context在 Glide 初始化中传入。 ConnectivityMonitor在RequestManager中使用,我们不可能把context 传到RequestManager中去吧?RequestManager只用于管理请求,不需要耦合android context 相关的,这样才符合单一职责原则,所以我们需要一个ConnectivityMonitorFactory工厂,RequestManager 作为Client 要使用ConnectivityMonitor, 只需要从ConnectivityMonitorFactory工厂中获得就行了。

从依赖倒置原则来看高层RequestManager 只依赖ConnectivityMonitorFactory和 ConnectivityMonitor抽象,不依赖具体实现细节,也是符合依赖倒置原则的。从接口隔离原则来看,RequestManager 需要感知网络状态只依赖ConnectivityMonitor和其工厂类,没有多余的接口依赖,也符合接口隔离原则。从里氏替换原则来看,ConnectivityMonitor 和ConnectivityMonitorFactory所有实现子类都可以出现在RequestManager,也符合里氏替换原则。从迪米特法则来看,RequestManager需要感知网络变化,需要用到context ,但又不是直接和context耦合,借助ConnectivityMonitor 来实现,也符合迪米特法则。

构建者设计模式

为什么要使用构建者设计模式 ?支持链式调用,避免构造参数列表过长,提高构造对象的灵活性和可配置性,使代码更加可维护

如GlideBuilder

使用Builder 模式,简化Glide 的创建,好处显而易见不多解释了。

原型模式

通过原型模式,我们可以根据一个现有对象创建出新的对象,并且可以灵活地修改新对象的属性,而不会影响原始对象。这样可以避免重复创建相似的对象,提高性能和代码复用性。克隆细分又分深拷贝和浅拷贝。听君一席话,如听一席话,我们看下Glide怎么做的。

Glide 哪里用到了原型模式呢? 在构建请求对象的请求参数就用到了,如下。

为什么要用clone,对应什么场景?其实就这个问题我也思考良久,让我们自己写图片加载框架估计就直接new 请求参数,然后把请求参数都塞进去,又不是不能用,这样确实是能用并且一点问题都没有。但是作为一个有梦想的程序员肯定是代码能优化地方就要优化的。例如下面这个场景

把一张图片加载到多个imageView 上面去,这种需求还是很常见的。这种情况下请求参数大部分信息都是可以共用的,就imageView不一样而已,我clone 一个出来复用大部分相同的请求参数信息,性能和内存不都优化了?何乐而不为,然后不同的部分 deep copy一下就行了。

行为型设计模式
观察者设计模式

glide 通过添加透明Fragment来监听activity /framgent 生命周期,这里提一下Glide为什么在子线程使用不会去监听生命周期,因为可能会导致内存泄露。在生命周期onDestroy 清理加载请求、onStop加载暂停、onStart恢复图片加载请求,用到了观察者设计模式。与之相关两个接口定义如下

LifecycleListener 是抽象观察者,方法有onStart/Stop/Destory,Lifecycle是抽象被观察者,方法有add/removeListener。RequestManager 作为具体观察者,实现了LifecycleListener。除了RequestManager实现了观察者接口是观察者外,还有ConnectivityMonitor ,TargetTracker,Target 都继承/实现LifecycleListener都是观察者,观察者比较简单不多讲了。

接下来讲讲glide 核心代码所用的责任链设计模式,通过责任链设计模式使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链发送该请求,直到有一个对象处理它为止。

责任链设计模式

如下 , ResourceCache(不需要解码和变换直接可以显示) ,DataCache(需要解码和变换) , Source 分别对应三个Generator,前两个从本地磁盘缓存中获取的图片数据,后面则直接从源(网络或者app本地资源文件中)Glide 按照配置依次从中获取图片加载数据。

这是责任链模式?怎么看都不像啊,责任链定义不是要将这些对象连成一条链,并沿着这条链发送该请求,直到有一个对象处理它为止。也就是说责任链模式都要有请求参数,就glide 而言这里给Generator的请求参数decodeHelper早在Generator初始化就传入了,就不用在startNext()方法中传入decodeHelper了。

代码都是死的,但是思想都是一样的,其实上面的代码也可以改成标准责任链模式。责任链设计模式有什么好处?责任链设计模式能够解耦请求发送者和接收者,简化对象之间的交互,提供灵活的处理顺序,使得系统更加灵活、可扩展和易于维护。它适用于需要动态组合和处理多个相关对象的场景,特别是在处理复杂的业务逻辑时,可以将复杂性分解成简单的处理步骤。

就Glide 而言,将解码请求发送者DecodeJob 高层对象和各种解码具体处理对象ResourceCacheGenerator等解耦,以及具体请求对象之间都通过责任链模式解耦了,DecodeJob作为高层对象无需关注解码细节,只需关注解码的整体流程就行。除了解耦之外还提供良好的扩展性,比如不需要从磁盘缓存中获取已解码的图片缓存, 只需要去掉return new ResourceCacheGenerator就行了,如下。

策略模式

glide 用于判断支不支持从磁盘缓存中获取图片就用到了策略模式

DiskCacheStrategy 有几个子类ALL 表示全部支持, NONE 什么都不支持。默认使用 AUTOMATIC 只有从网络才支持Data 缓存,并且从网络获取中如果使用了Data 缓存则不支持ResourceCache。我们要改缓存策略的话可以在请求参数中修改DiskCacheStrategy。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数HarmonyOS鸿蒙开发工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年HarmonyOS鸿蒙开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上HarmonyOS鸿蒙开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新

如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注鸿蒙获取)
img

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

.(img-vE8kW2az-1712656959801)]

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐