淘宝iOS扫一扫架构升级 - 设计模式的应用

网站建设3年前发布
73 0 0

扫一扫是淘宝镜头页中的一个重要组成,功能运行久远,其历史代码中较少采用面向对象编程思想,而较多采用面向过程的程序设计。随着扫一扫功能的不断迭代,我们基于设计模式的基本原则,逐步采用设计模式思想进行代码和架构优化。本文就是在这个背景下,对设计模式在扫一扫中新的应用进行了总结。扫一扫原架构,如图所示。其中逻辑&展现层的功能逻辑很多,并没有良好的设计和拆分,举几个例子:,按照现有的代码设计,若要对某种码逻辑进行修改,都必须将所有逻辑全量编译。如果继续沿用此代码,扫一扫的可维护性会越来越低。,2023030612135835af6a493bce1a931e38604fc831b9e17aeffc230,因此我们需要对代码和架构进行优化,在这里优化遵循的思路是:,扫一扫的解码能力决定了扫一扫能够处理的码类型,这里称为一级分类。基于一级分类,扫一扫会根据码的内容和类型,再进行二级分类。之后的逻辑,就是针对不同的二级类型,做相应的处理,如下图为技术链路流程。,20230306121359938a27b457a0e43e04f6906a19b63e448749aa387,2023030612140056b593b283570177da571795a66202f94ed1b8796,上述技术链路流程中,码处理流程对应的就是原有的 viewController 里面的巨无霸逻辑。通过梳理我们看到,码处理其实是一条链式的处理,且有前后依赖关系。优化方案有两个,方案一是拆解成多个方法顺序调用;方案二是参考苹果的 NSOperation 独立计算单元的思路,拆解成多个码处理单元。方案一本质还是没解决开闭原则(对扩展开放,对修改封闭)问的题。方案二是一个比较好的实践方式。那么怎么设计一个简单的结构来实现此逻辑呢?,码处理链路的特点是,链式处理,可控制处理的顺序,每个码处理单元都是单一职责,因此这里引出改造第一步:责任链模式。,责任链模式是一种行为设计模式, 它将请求沿着处理者链进行发送。收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。本文设计的责任链模式,包含三部分:,‍三者结构如图所示,20230306121401a2b337398887ec22a1c313723f7449f7ea349a970,包含的功能和特点:,API 代码示例如下,上层业务代码示例如下,包含的功能和特点:,API 代码示例如下,实现代码示例如下,包含的功能和特点:,1.因为数据是基于业务的,所以它只被声明为一个 Protocol ,由上层实现。,API 代码示例如下,上层业务代码示例如下,有了上述的框架和上层实现,生成一个码处理管理就很容易且能达到解耦的目的,代码示例如下,20230306121402041665f6442fb0f36649177fda1b83d8fc8fbb524202303061214033218d16144d35cc149d492350029e4ef09db3d169,回头来看下码展示的逻辑,这是我们用户体验优化的重要一项内容。码展示的意思是对于当前帧/图片,识别到的码位置,我们进行锚点的高亮并跳转。这里包含三种情况:,可以看到,这里涉及到简单的展示状态切换,这里就引出改造的第二步:状态模式,20230306121404355772a42c8cd10cfc8108a47924b344483168207,
,状态模式是一种行为设计模式, 能在一个对象的内部状态变化时改变其行为, 使其看上去就像改变了自身所属的类一样。,本文设计的状态模式,包含两部分:,两者结构如图所示,2023030612140753eade7363710dc90306281c630b2e459e5696175,包含的功能和特点:,状态信息的声明和实现代码示例如下,上层业务代码示例如下,包含的功能和特点:,Protocol 如下,基类为空实现,子类继承后,实现对 StateInfo 的处理。,上层(以单码 State 为例)代码示例如下,以下代码生成一系列状态,在合适时候进行状态的切换。,最好根据状态机图编写状态切换代码,以保证每种状态都有对应的流转。,代理模式,20230306121408a1a01c806cd1096cc3449041fc090c8481aedc187,在开发过程中,我们会在越来越多的地方使用到上图能力,比如「淘宝拍照」的相册中、「扫一扫」的相册中,用到解码码展示码处理的能力。,因此,我们需要把这些能力封装并做成插件化,以便在任何地方都能够使用。这里就引出了我们改造的第三步:代理模式。,代理模式是一种结构型设计模式,能够提供对象的替代品或其占位符。代理控制着对于原对象的访问, 并允许在将请求提交给对象前后进行一些处理。,本文设计的状态模式,包含两部分:,两者结构如图所示,20230306121423754d06b1718002bd45591530501f3278658668602,单例的目的主要是减少代理重复初始化,可以在合适的时机初始化以及清空保存的内容。单例模式对于 iOSer 再熟悉不过了,这里不再赘述。,维护一个对象,提供了对代理增删改查的能力,实现对代理的操作。这里实现 Key - Value 的 Key 为 Protocol ,Value 为具体的代理。,代码示例如下,所以不管是什么业务方,只要是需要用到对应能力的地方,只需要从单例中读取 Proxy, 实现该 Proxy 对应的 Protocol, 如一些回调、获取当前上下文等内容,就能够获取该 Proxy 的能力。,‍基于上述的改造优化,我们将原扫一扫架构进行了优化:将逻辑&展现层进行代码分拆,分为展现层逻辑层接口层。以达到层次分明、职责清晰、解耦的目的。,20230306121409c18dc999058ba0f567a8054864f3b980b07608458,上述沉淀的三个设计模式作为扫拍业务的 Foundation 的  Public 能力,应用在镜头页的业务逻辑中。通过此次重构,提高了扫码能力的复用性,结构和逻辑的清晰带来的是维护成本的降低,不用再大海捞针从代码“巨无霸”中寻找问题,降低了开发人日。

© 版权声明

相关文章