商业iOS端路由架构演进

背景

目前商业SDK中的点击事件,会根据不同的「事件类型」+「业务类型」,去执行不同的路由跳转逻辑,然而不同的跳转事件内部又有着很复杂的跳转逻辑,

痛点

  1. 不同的跳转逻辑之间存在耦合
    例如,在deeplink的跳转逻辑之中有其他跳转逻辑,如果dp失败后会走normal的路由跳转;或者有些业务有deeplink链接的时候跳转dpplink,没有dp的时候会跳转默认的链接。
  2. 代码可读性差,维护成本高
    在某一个click事件当中,由于产品特性,可能会包含多个跳转逻辑,例如:跳转视频、跳转网页等等。
  3. 排查问题的难度增加

基于以上现状,在排查跳转问题的时候,需要花费较长的时间去梳理代码。

现状流程图

在这里插入图片描述

可以从上图看出,跳转逻辑相互关联,对于代码流程处理异常艰难。

优化想法

  1. 由于每一个卡片跳转都有一定的顺序和流程。我们需要整体先后顺序。

  2. 拉产品沟通,将跳转的先后顺序以及 成功的条件进行沟通。

沟通后流程如图:

请添加图片描述

方案

初步想的方案是,根据跳转的页面的优先级,做一个类似链表的结构体,然后链表的每个子元素都是一个页面跳转流程。 根据「页面跳转的成功」条件去进行判断,如果某个子元素跳转成功,那么returen掉,如果失败,那么继续走到下一个链表的子元素。以此类推,最终走向兜底逻辑。

原理其实很简单,就是一个链式表达式,哪个成功那么就跳转哪个,后边的流程不执行。

调用方式如下:


//构建各个路由跳转的元素成链条     var routers: [ChainedRouter] = [RouterA(), RouterB(), RouterC(), RouterD()...]// 通过方法调用,并传入对应的字段routers.chain()?.route(with: dataA, dataB: dataB, other: otherMessage)

优化架构图:

在这里插入图片描述

优化流程图

在这里插入图片描述

调用方式参考


//构建各个路由跳转的元素成链条     var routers: [ChainedRouter] = [RouterA(), RouterB(), RouterC(), RouterD()...]// 通过方法调用,并传入对应的字段routers.chain()?.route(with: dataA, dataB: dataB, other: otherMessage)

核心代码分享

protocol HmgRouter: AnyObject {// 只需看当前响应者是否响应,不需要处理责任链传递func tryToRoute(with model: NSObject?, context: [String: Any]?,  completionHandler: @escaping ((Bool) -> Void))
}protocol HMGChainedRouter: HmgRouter, HmgRouterLifeCycle {var next: HMGChainedRouter? { get set }
}protocol HmgRouterLifeCycle: AnyObject {var success: (() -> Void)? { get set }var failed: (() -> Void)? { get set }func lifeCycleCallBack(_ result: Bool)
}extension HmgRouterLifeCycle {func lifeCycleCallBack(_ result: Bool) {if result {if let success = success {success()}} else {if let failed = failed {failed()}}}
}extension HMGChainedRouter {func route(with model: NSObject?, context: [String: Any]?,  completionHandler: ((Bool) -> Void)?) {tryToRoute(with: model, context: context, viewAction: viewAction) { res inif !res, let next = self.next {next.route(with: model, context: context, viewAction: viewAction, completionHandler: completionHandler)}completionHandler?(res)}}
}class HmgRouterBuilder {private var top: HMGChainedRouter?private var tail: HMGChainedRouter?func add(_ router: HMGChainedRouter) -> Self {if top == nil {top = routertail = router} else {tail?.next = routertail = router}return self}func clean() -> Self {top = niltail = nilreturn self}func build() -> HMGChainedRouter? {return top}
}extension Array where Element == HMGChainedRouter {func chain() -> Element? {let a: (HMGChainedRouter?, HMGChainedRouter?) = (nil, nil)return reduce(a) { (res, current) inlet (top, tail) = resguard let h = top else {return (current, current)}tail?.next = currentreturn (h, current)}.0}
}

思考

本文中的实现方式其实就是一种责任链的实现。 我的另一篇文章详细介绍了一个责任链模式的使用场景以及常规的实现方式。 责任链模式是代码中经常要用到的。责任链其实就是某个业务场景下每个处理理单元负责一部分任务,形成一个连续处理的链条,直到任务被处理或无人处理。这种模式使得代码结构清晰,易于扩展。

附上责任链文章:https://blog.csdn.net/liyunxiangrxm/article/details/130827650

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/474800.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构(单向链表——c语言实现)

链式存储的优缺点: 优点: 1、动态分配内存: 链式存储不需要在数据插入之前分配固定大小的数组或内存块,因此它更适合存储动态变化的数据 2、高效的插入和删除操作: 在链表中插入或删除元素只需要调整相邻节点的指…

【SQL】E-R模型(实体-联系模型)

目录 一、介绍 1、实体集 定义和性质 属性 E-R图表示 2. 联系集 定义和性质 属性 E-R图表示 一、介绍 实体-联系数据模型(E-R数据模型)被开发来方便数据库的设计,它是通过允许定义代表数据库全局逻辑结构的企业模式&#xf…

Pytest-Bdd-Playwright 系列教程(12):步骤参数 parsers参数解析

Pytest-Bdd-Playwright 系列教程(12):步骤参数 & parsers参数解析 前言一、什么是步骤参数?二、pytest-bdd 的步骤参数用法2.1 简单字符串解析2.2 自定义正则表达式解析2.3 参数类型转换 三、案例:基于 pytest-bdd…

vscode 快捷键生成代码

1. !Tab/回车键 便捷生成html初始结构代码(注意!是英文字符) 2. Alt B 快捷默认浏览器打开 3. Ctrl / 增加注释 4. 光标放到该行即可,直接ctrlC,ctrlv,即可在下面复制一行 5. 选中要修改的标签…

前端接入Paymax支付请求

材料指南 开发者平台 :配置开发必备信息(appid,商户号,公钥私钥),此处与请求参数appId、merchantNo有关。 PayerMax Apis:各支付接口信息,本文以收银台支付API为请求展开,请求url为orderAndPay,测试环境基…

Jmeter的后置处理器(二)

5--JSR223 PostProcessor 功能特点 自定义后处理逻辑:使用脚本语言编写自定义的后处理逻辑。支持多种脚本语言:支持 Groovy、JavaScript、BeanShell 等脚本语言。动态参数传递:将提取的数据存储为变量,供后续请求使用。灵活性高…

CSS遮罩:mask

CSS属性 mask 允许使用者通过遮罩或者裁切特定区域的图片的方式来隐藏一个元素的部分或者全部可见区域。 // 一般用位图图片做遮罩 mask: url(~/assets/images/mask.png); mask-size: 100% 100%;// 使用 SVG 图形中的形状来做遮罩 mask: url(~/assets/images/mask.svg#star);…

Zmap+python脚本+burp实现自动化Fuzzing测试

声明 学习视频来自 B 站UP主泷羽sec,如涉及侵权马上删除文章。 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负。 ✍🏻作者简介:致…

15. Python中的os.path模块/路径操作相关

这个专栏记录我学习/科研过程中遇到的一些小问题以及解决方案,一些问题可能比较蠢请见谅。自用,仅供参考。 ------------------------------------------------------------------------------------ Python中的os.path模块详解(包括一些常…

鸿蒙实战:页面跳转传参

文章目录 1. 实战概述2. 实现步骤2.1 创建鸿蒙项目2.2 编写首页代码2.3 新建第二个页面 3. 测试效果4. 实战总结 1. 实战概述 本次实战,学习如何在HarmonyOS应用中实现页面间参数传递。首先创建项目,编写首页代码,实现按钮跳转至第二个页面并…

NLP论文速读(EMNLP 2024)|动态奖励与提示优化来帮助语言模型的进行自我对齐

论文速读|Dynamic Rewarding with Prompt Optimization Enables Tuning-free Self-Alignment of Language Models 论文信息: 简介: 本文讨论的背景是大型语言模型(LLMs)的自我对齐问题。传统的LLMs对齐方法依赖于昂贵的训练和人类偏好注释&am…

Label-studio-ml-backend 和YOLOV8 YOLO11自动化标注,目标检测,实例分割,图像分类,关键点估计,视频跟踪

这里写目录标题 1.目标检测 Detection2.实例分割 segment3.图像分类 classify4.关键点估计 Keypoint detection5.视频帧检测 video detect6.视频帧分类 video classify7.旋转目标检测 obb detect8.替换yolo11模型 给我点个赞吧,谢谢了附录coco80类名称 笔记本 华为m…

图像处理学习笔记-20241118

文章目录 霍夫变换基本原理霍夫变换的步骤使用 OpenCV 实现直线检测示例:标准霍夫变换 示例:概率霍夫变换参数解释霍夫变换检测圆 基于GAN的样本生成GAN的基本原理基于GAN的数据增广流程实现代码示例 同态滤波(Homomorphic Filtering&#xf…

视频融合×室内定位×数字孪生

随着物联网技术的迅猛发展,室内定位与视频融合技术在各行各业中得到了广泛应用。不仅能够提供精确的位置信息,还能通过实时视频监控实现全方位数据的可视化。 与此同时,数字孪生等技术的兴起为智慧城市、智慧工厂等应用提供了强大支持&#…

当科技照进现实 机器人带着机器狗乘空轨

湖北日报讯(记者魏铼、通讯员张璨龙)11月14日,武汉东湖高新区空轨高新大道站,在光谷装上“智慧大脑”的人形机器人,乘空轨,看AI展,与小朋友在生态大走廊斗舞。 京天博特:光谷“智慧大…

freertos任务调度学习

首先创建任务,创建好任务后,开启任务调度器,任务才能执行 1.开启任务调度器 2.启动第一个任务 3.任务切换

蓝桥杯每日真题 - 第16天

题目:(卡牌) 题目描述(13届 C&C B组C题) 解题思路: 题目分析: 有 n 种卡牌,每种卡牌的现有数量为 a[i],所需的最大数量为 b[i],还有 m 张空白卡牌。 每…

MySQL系列之数据授权(privilege)

导览 前言Q:如何对MySQL数据库进行授权管理一、MySQL的“特权”1. 权限级别2. 权限清单 二、授权操作1. 查看权限2. 分配权限3. 回收权限 结语精彩回放 前言 看过博主上一篇的盆友,可以Get到一个知识点:数据授权(eg:g…

C++为函数提供的型特性——缺省参数与函数重载

目录 一、缺省参数 二、函数重载 一、缺省参数 C为函数提供了一项新的特性——缺省参数。缺省参数指的是当前函数调用中省略了实参自动使用的一个值。这极大地提高了函数的灵活性 缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值 。在调⽤该函数时,如果没有…

android 使用MediaPlayer实现音乐播放--权限请求

在Android应用中,获取本地音乐文件的权限是实现音乐扫描功能的关键步骤之一。随着Android版本的不断更新,从Android 6.0(API级别23)开始,应用需要动态请求权限,而到了android 13以上需要的权限又做了进一步…