iOS Coordinator 实战
source link: https://nemocdz.github.io/post/ios-coordinator-%E5%AE%9E%E6%88%98/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
iOS Coordinator 实战
@Nemocdz · Jun 13, 2021 · 1 min read
大部分 iOS 开发者会在 UIViewController
里编写 present
/push
的代码展示另一个 UIViewController
,也习惯响应关闭按钮的点击事件后调用 dismiss
/ pop
来关闭自身。
这样有什么问题?
- 难以复用:展示方式写死了,不同场景要写
if
/else
- 灵活性低:页面展示的流程是固定的,难以插入或去掉
- 耦合性高:依赖了其他
UIViewController
的类信息(甚至更多) - 职责不合理:
UIViewController
知道被放在 navigation 或者 tab 中,也知道自己的展现形式 - 维护成本高:负责了这部分职责后,
UIViewController
的代码会膨胀
举个简单例子:
引入一个通用的角色,负责页面转场/流程的组合和调度,这就是 Coordinator(协调者)。
Coordiantor 的职责:
- 新建和切换画面
- 组合多个子页面为复杂界面
- 实现页面间的回调接收/代理,转换为其他页面需要的数据
上面的例子通过引入 Coordinator 层,整体架构如下:
第一次重构
根据上述思想,可以给每一个 UIViewController
搭配一个对应的 Coordinator
,这样重构之后,UIViewController
之间没有显式耦合,需要改动流程和展示方式时不需要修改 UIViewController
中的代码,代码变得干净和职责分明。
CoordinatorDemo-first refactor
第二次重构
第一次重构后,代码职责已经清楚了,基本达到架构演进的目的。接下来可以考虑怎么让代码更优雅。这里面虽然 UIViewController
之间没有显式依赖了,但是由于显式依赖了 Coordinator
,其中有其他 UIViewController
的依赖,所以还存在间接依赖。解决这个问题也很简单,引入 Protocol,将 Coordinator
的结构抽象成协议,而非具体的类,这样耦合就被彻底拆开了。在不同宿主底下,可以使用不同的实现。
CoordinatorDemo-second refactor
第三次重构
第二次重构后,回头看看开头的几个问题
- 展示方式通过不同的实现解决
- 流程通过不同
Coordinator
连接 UIViewController
之间没有耦合UIViewController
不感知自己被如何展示UIViewController
中的代码减少了
问题基本得到解决。更进一步思考在 iOS 上,还可以通过什么手段来更使 Coordinator
更强大呢?如果将 Coordinator
继承自 UIViewController
,而将原来的 UIViewController
作为 Coordinator
的 childController
。
可以获得以下特性:
Coordinator
不需要由UIViewController
持有,而是由系统管理UIViewController
对Coordinator
的依赖变成了 Delegate,可以不依赖Coordinator
协议- 可以使用
childController
的add
/remove
进行管理 - 能承担响应链和
UITraitCollection
等UIViewController
才有的特性
经过重构后所谓的 Coordinator 就是其实就是原来的 UIViewController
,而将其展示的部分拆成了新的 childController
专门用于视图展示和处理(在有些文章中也被称为 FlowController
)。
CoordinatorDemo-third refactor
项目中可以根据需要进行演进,第一次重构已经能实现拆分的思想,第二次重构增加了灵活性,第三次重构依赖了 iOS 目前已有的 API,在架构上反而不是一件太好的事情,因为不同的系统能力不一定对齐,甚至在同系统上(比如引入 Flutter
、SwiftUI
后)也不一定能够长久使用。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK