写点什么

【技研录】响应式编程在 Swift 中的使用

  • 2023-11-24
    北京
  • 本文字数:3225 字

    阅读完需:约 11 分钟

【技研录】响应式编程在 Swift 中的使用

写作思考:

响应式编程(Reactive Programming)是一种编程范式,它以数据流和变化传递为核心概念,可以简化代码结构,提高程序的可读性和可维护性。在 Swift 中,响应式编程已经得到了广泛的应用,并成为了一些流行框架的基础,开发者可以通过框架提供的操作符对数据流进行各种变换。目前在众安科技经代 App 中全面使用,整体代码逻辑更加清晰,开发效率上得到了明显的提升。


目录

1.什么是响应式编程

2.函数式 Swift

3.MVVM

4.MVVM 与响应式结合

5.总结


一.什么是响应式编程

 

Wiki 上的解释: Reactive programming 是一种面向数据串流和变化传播的声明式编程范式。

iOS 客户端的原生开发使用 Objective-C 和 Swift 开发,使用 Objective-C 的时候注重面向对象编程,大多数都是使用命令式的编程,Swift 更注重面向协议编程、函数式编程。

 

做过 iOS 客户端的同学一定了解过 KVO 这个内置的 Api,KVO 可以帮助我们将属性的变更和变更后的处理分开,简单的理解就是一个对象的属性改变后,另外一连串对象的属性都随之发生改变。KVO 的写法和使用上比较复杂,而且只支持 NSObject ,局限性太大。 

 

Apple 在推出 Swift 之后,响应式的编程基于数据流的理念,异步的处理事件和函数式编程能很好的结合,ReactiveX 推出了响应式的库 RxSwift,WWDC 2019 上 Apple 公布了声明式全新界面框架 SwiftUI,以及配套的响应式编程框架 Combine,Combine 只支持 iOS13 以上的系统,毕竟属于原生的框架,在性能上要稍微强于 RxSwift,根据支持的版本差异开发者可以自行选择。 

 

最新推出 Rx 的微软对响应式编程的解释是 Rx = Observables + LINQ + Schedulers,通俗一些的解释就是面向异步数据流编程。数据流可以有多种形式,比如读取一个文件、进行一个网络请求、用户出发的行为等等,都可以认为是一种数据流,当然一个变量也可以认为是一种数据流。

                                   

二.函数式 Swift

 

函数式编程中的函数这个词不是指计算机中的函数,而是指数学中的函数,即自变量的映射。也就是说一个函数的值仅决定于函数参数的值,不依赖其他状态。比如 sqrt(x) 函数计算 x 的平方根,只要 x 不变,不论什么时候调用,调用几次,值都是不变的。


1. 一等公民函数与高阶函数


在函数式编程中,函数是一等公民,不再把函数想象成一个处理过程,而是把它当作一个对象或者变量来对待。

 

 

在 Swift 中可以很方便的把一个函数赋值给一个常量,这个在 Objective-C 中是做不到的。所谓的高阶函数,指可以将其他函数作为参数或者返回结果的函数,Swift 中的函数都是高阶函数,系统库提供了(map,fillter,reduce 等)

 


通过函数这个“管道”,数据从一头经过“管道”到另一头,就得到了想要的数据。

 

2.柯里化

 

Swift 里可以将方法进行柯里化 (Currying),这是也就是把接受多个参数的方法进行一些变形,使其更加灵活的方法。函数式的编程思想贯穿于 Swift 中,而函数的柯里化正是这门语言函数式特点的重要表现。

 


柯里化是一种量产相似方法的好办法,可以通过柯里化一个方法模板来避免写出很多重复代码,也方便了今后维护。

 

3.闭包

 

闭包是一个会对它内部引用的所有变量进行隐式绑定的函数。也可以说,闭包是由函数和与其相关的引用环境组合而成的实体。函数实际上是一种特殊的闭包,你可以使用{ }来创建一个匿名闭包。使用 in 来分割参数和返回类型。

 


上面 map 函数遍历了数组,用闭包处理了所有元素,并返回了一个处理过的新数组。

那么遵循以上特性,一个好的 Swift 函数式程序会具有一下特质:

 

  ● 模块化:相较于把程序认为是一系列赋值和方法调用,函数式开发者更倾向于强调每个程序都能够被反复分解为越来越小的模块单元,而所有这些块可以通过函数装配起来,以定义一个完整的程序。

 

  ● 对可变状态的谨慎处理:面向对象编程专注于类和对象的设计,每个类和对象都有它们自己的封装状态。然而,函数式编程强调基于值编程的重要性,这能使我们免受可变状态或其他一些副作用的困扰。通过避免可变状态,函数式程序比其对应的命令式或者面向对象的程序更容易组合。

 

  ● 类型:一个设计良好的函数式程序在使用类型时应该相当谨慎。精心选择你的数据和函数的类型,将会有助于构建你的代码,这比其他东西都重要。Swift 有一个强大的类型系统,使用得当的话,它能够让你的代码更加安全和健壮。

 

在实际开发过程中,我们遵循函数式思维去编码,可以很容易地使用 Swift 写出函数式风格的代码,为我们带来以下好处:

 

1. 方便组件解耦

2. 单元测试和调试都更容易

3. 更方便的代码管理

 

三.MVVM

 

MVVM 可以说几乎就是一个 MVC,不过通过 View Model 层来将数据和视图进行绑定。熟悉 iOS 开发的小伙伴都知道,iOS 的 Cocoa 框架都是基于 MVC 设计的,关于 MVC,我们可以看下斯坦福的 CS193p Paul 这张经典图



MVC 本身的概念相当简单,同时它也给了开发者很大的自由度。Massive View Controller 往往就是利用了这个自由度,“随意”地将逻辑放在 Controller 层所造成的后果,此时的 M 不是 Model 已经变成了 Massive。



使用 MVVM 之后可以大大减轻 View Controller 职责,简化后的各个模块分工更加明确,更加方便集成和开发。我们在使用的时候主要遵循一下几个事项:

    ●  ViewController 尽量不涉及业务逻辑,让 ViewModel 去做这些事情,此时的 ViewModel 实际上的职责是 Controller

    ● ViewModel 绝对不能包含视图 View(UIKit.h),不然就跟 View 产生了耦合,不方便复用和测试

    ● iewModel 避免过于臃肿,否则重蹈 Controller 的覆辙,变得难以维护

 

MVVM 是 MVC 的升级版,完全兼容当前的 MVC 架构,MVVM 虽然促进了 UI 代码与业务逻辑的分离,一定程度上减轻了 ViewController 的臃肿度,但是 View 和 ViewModel 之间的数据绑定使得 MVVM 变得复杂和难用了,如果我们不能更好的驾驭两者之间的数据绑定,同样会造成 Controller 代码过于复杂,代码逻辑不易维护的问题。


四.MVVM 与响应式结合

 

上面介绍完 MVVM,那应该怎么和响应式结合起来呢?我们先来看下在 iOS 中是怎么进行状态更新的

  ● Target-Action

  ● Delegate

  ● KVO

  ● Notifications

  ● Callback

 

多种回调方式,适用规则、适用场景都不相同,这增加了开发、维护的难度。如果有一种方式可以把状态更新做到统一,那就可以大大提高开发效率,这里就要提到 Rx 了,它把状态变更都转化成流,MVVM 中的 ViewModel 和 Rx 相结合这样就可以做到响应式了。

 

先来看个例子,一个登录界面



产品经理说了需求:

  ● 账号是手机号 11 位

  ● 密码大于 6 位

  ● 当满足上面条件,点击统一条款,下面登录按钮为可点击状态否则不可点击

 

按照一般思路,2 个输入框对应的是 2 个 UITextField 控件,还有 2 个 UIButton 控件对应单选按钮和登录按钮,我们需要实现这个需求就要做到以下:

  1. 在 UITextField 的 Delegate 里面去监听输入的内容

  2. 在 UIButton 的 Action 方法里面监听隐私条款是否点击

  3. 2 个输入框和 1 个隐私按钮,这 3 个控件每次更新状态都要去看另外 2 个是否满足登录按钮可点击

 

可以见到这样一个简单的需求,在代码实现上要处理的逻辑很多,而且都是分散的,那么我们能不能只罗列条件,然后把这些条件扔给一个条件处理的机制,这个机制就能帮我们正确的处理这些关系?

 

 

伪代码如下:


 

实际处理中会把这些逻辑放到 ViewModel,这样就把 RxSwift,函数式,MVVM 结合起来,达到了响应式编程的样子。

 

五.总结

 

Swift 从 2014 年发布,到 iOS13 推出的响应式 Combine,开源也一直推动语言的发展,可能未来 1 天苹果会抛弃原来 Cocoa 框架实现,利用新语言的特性也不是不可能。任何架构和技术都不能满足所有的工程需求,能够使用简单的架构来搭建复杂的工程,制作出让其他开发者可以轻松理解的软件,避免高额的后续维护成本,让软件可持续发展并长期活跃,应该是每个开发者在构建软件是必须考虑的事情。

 

参考资料:

 

  1. 关于 MVC 的一个常见的误用

  2. iOS 下的响应式编程

公众号推荐:

跳进 AI 的奇妙世界,一起探索未来工作的新风貌!想要深入了解 AI 如何成为产业创新的新引擎?好奇哪些城市正成为 AI 人才的新磁场?《中国生成式 AI 开发者洞察 2024》由 InfoQ 研究中心精心打造,为你深度解锁生成式 AI 领域的最新开发者动态。无论你是资深研发者,还是对生成式 AI 充满好奇的新手,这份报告都是你不可错过的知识宝典。欢迎大家扫码关注「AI前线」公众号,回复「开发者洞察」领取。

2023-11-24 16:59669

评论

发布
暂无评论
发现更多内容

DApp开发搭建公司指南:在去中心化未来中创造价值

西安链酷科技

DAPP智能合约交易系统开发 DAPP系统开发

万字长文教你实现华为云IoT+OpenHarmony智能家居开发

华为云开发者联盟

鸿蒙 物联网 华为云 华为云开发者联盟 企业号9月PK榜

文盘Rust -- tonic-Rust grpc初体验 | 京东云技术团队

京东科技开发者

rust gRPC 虚拟操作系统 企业号9月PK榜

Multitrack Editor for Mac(多轨音频编辑软件) v1.0.5完美激活版

mac

苹果mac 音频编辑软件 Windows软件 Multitrack Editor

第1期 | 抚今 现代企业已步入新的项目制管理时代

用友BIP

项目管理

去中心化交易所搭建|区块链数字货币交易平台开发

西安链酷科技

交易所开发 交易所源码 交易所搭建

NFTScan Meetup 上海站主题分享:TON 的发展现状与未来展望

NFT Research

NFT\

IPQ4019 802.11a/b/g/n/ac-802.11ax IPQ5018 WiFi standards as motherboard chips IIOT application

wifi6-yiyi

IPQ4019 802.11AX

用友iuap 技术平台:创新基础架构,赋能企业数智化转型

用友BIP

数智底座 2023全球商业创新大会

【ChatGPT-应用篇】基于chatGPT覆盖测试过程的初步探索 | 京东物流技术团队

京东科技开发者

人工智能 测试 ChatGPT 企业号9月PK榜

坐标休斯顿,TDengine 受邀参与第九届石油天然气数字化大会

TDengine

时序数据库 #TDengine

Amazon Lightsail——兼具亚马逊云科技的强大功能与 VPS 的简易性

亚马逊云科技 (Amazon Web Services)

Hologres RoaringBitmap实践:千亿级画像数据秒级分析

阿里云大数据AI技术

大数据 阿里云

微调语言模型前,需要考虑这三个关键方面

Baihai IDP

AI LLM 白海科技 大模型微调 Baihai IDP

分布式系统的主键生成方案对比 | 京东云技术团队

京东科技开发者

分布式系统 uuid 企业号9月PK榜 主键生成

简单好用的音频播放器:Infuse 激活中文最新版

胖墩儿不胖y

媒体播放器 Mac软件 播放器推荐

一文详解数据仓库的物理细粒度备份恢复

华为云开发者联盟

数据库 大数据 华为云 华为云开发者联盟 企业号9月PK榜

交易所开发 通过定制解决方案获得优势:加密货币交易服务

区块链软件开发推广运营

交易所开发 数字藏品开发 dapp开发 区块链开发 链游开发

软件测试/测试开发丨​利用ChatGPT编写测试用例

测试人

软件测试 测试开发 ChatGPT

第五期 PaddlePaddle Hackathon 飞桨黑客马拉松热身赛上线!

飞桨PaddlePaddle

深度学习 编程、

推送服务本地通知频次及分类管控通知

HMS Core

HMS Core

iOS16新特性:实时活动-在锁屏界面实时更新APP消息 | 京东云技术团队

京东科技开发者

iOS16 企业号9月PK榜 Live Activity

基于开源IM即时通讯框架MobileIMSDK:RainbowChat v10.0版已发布

JackJiang

网络编程 即时通讯 IM

DR6018|IPQ6010 IPQ6018 WiFi6 2X2 QSDK OpenWiFi Cloud AP AC Customizable Solution

wallyslilly

IPQ6010 ipq6018

磁盘垃圾清理软件推荐 Magic Disk Cleaner 激活中文版

mac大玩家j

Mac软件 磁盘清理工具 磁盘清理优化软件

灞桥康养论坛圆满落幕 灞桥康养“四片区”邀您遇见新西安

联营汇聚

小灯塔系列-中小企业数字化转型系列研究——进销存测评报告

人称T客

http代理ip服务器有哪些?代理服务器有什么作用?

巨量HTTP

代理IP http代理

“融合康养产业、乐享宜居灞桥”灞桥康养论坛成功举办

联营汇聚

TDengine 与煤矿智能 AI 视频管理系统实现兼容性互认

TDengine

时序数据库 #TDengine 恒达智控

人民日报发文祝贺,这位作者是藏不住了!

博文视点Broadview

【技研录】响应式编程在 Swift 中的使用_云计算_众安保险_InfoQ精选文章