商业iOS端路由架构演进

背景

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

痛点

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

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

现状流程图

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

优化想法

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

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

沟通后流程如图:

方案

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

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

调用方式如下:

objectivec 复制代码
//构建各个路由跳转的元素成链条     

var routers: [ChainedRouter] = [RouterA(), RouterB(), RouterC(), RouterD()...]

// 通过方法调用,并传入对应的字段

routers.chain()?.route(with: dataA, dataB: dataB, other: otherMessage)

优化架构图:

优化流程图

调用方式参考

objectivec 复制代码
//构建各个路由跳转的元素成链条     

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 in
            if !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 = router
            tail = router
        } else {
            tail?.next = router
            tail = router
        }
        return self
    }
 
    func clean() -> Self {
        top = nil
        tail = nil
        return 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) in
            let (top, tail) = res
            guard let h = top else {
                return (current, current)
            }
            tail?.next = current
            return (h, current)
        }.0
    }
}

思考

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

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

相关推荐
车载诊断技术5 小时前
电子电气架构 --- 电子电器新技术及发展趋势
网络·架构·汽车·电子电器框架·车载充电器(obc)·电子电器新技术及发展趋势
呱牛do it5 小时前
【系列专栏】银行IT的云原生架构-混合云弹性架构 13
微服务·云原生·金融·架构
uhakadotcom7 小时前
约束求解领域的最新研究进展
人工智能·面试·架构
文军的烹饪实验室10 小时前
我国有哪些芯片使用的是arm架构处理器
arm开发·架构
微学AI12 小时前
Deepseekv3原理架构中的数学公式,通过高度概括实现快速入门
开发语言·人工智能·python·架构·deepseek
martian66513 小时前
【Java高级篇】——第13篇:深入探讨设计模式与Java实践
java·开发语言·架构
power-辰南14 小时前
AI Agent架构深度解析:从ReAct到AutoGPT,自主智能体的技术演进与工程实践
人工智能·react.js·架构·ai agent
hope_wisdom17 小时前
实战设计模式之外观模式
设计模式·架构·软件工程·软件构建·外观模式·架构设计
调皮的芋头20 小时前
【架构思维基础:如何科学定义问题】
大数据·阿里云·架构·云计算
何小Ai同学1 天前
Deepseek赚钱密码:小场景闭环如何让你快速盈利?
人工智能·架构·deepseek