Swift-ier Redux实施-第一部分

这是一系列中级帖子的第一个。 第二部分即将推出 如果您是忙碌的开发人员,请随时跳过本文,直接转到代码: https : //github.com/wircho/Swux

React + Redux组合提供了一个非常强大的Web反应模型,隐藏了反应体系结构令人困惑的一面,并提供了可读且具有同步外观的应用程序代码。

下图概括了Redux背后的范式,即单向数据流

商店实体独自负责使用一种称为reducer的函数来改变和提供应用程序状态 (该值包含在任何时间点唯一确定应用程序UI所需的所有信息),并且该函数具有旧状态和一个action ,以及返回新状态。 该应用可能会调度 (提交) 商店排队的动作以连续改变应用状态并通知订户 。 订阅者收到新状态后,必须使用它来更新应用程序的UI。

当我进行移动开发时,有时会想念这种范例的简单性,因为大型项目有时会变成反应性元素,回调和委托的混杂体。 因此,我最近决定探索ReSwift,并确定它在Swift中是否与原始JavaScript工具一样好。

在大多数情况下是这样,但不难看出它怎么可能更快。 一个示例是reducer函数的签名(从此处开始):

  (_动作: 动作 ,_状态: 状态 ?)-> 状态 

在Swift中,该签名可以做成:

  (_动作: 动作 ,_状态:进入状态 ?)-> 无效 

实际上,虽然第一种形式迫使您创建状态的副本或全新状态,但是第二种形式使您可以更改状态,从而在更少的行中编写更具可读性的代码。 由于Swift的写时复制值类型和专有所有权功能,该代码还可以更快地运行并且使用更少的内存。

我也不喜欢这种类型转换(来自ReSwift的README.md)的switch语句,它的形式是从JavaScript借来的:

  func reducer (操作: 操作 ,状态: AppState吗?)-> AppState { 
var state =状态?? AppState ()

切换动作{
案例_作为CounterActionIncrease
state.counter + = 1
案例_作为CounterActionDecrease
state.counter-= 1
默认:
打破
}

返回状态
}

一些Swift开发人员会告诉您完全避免进行可选的强制转换( foo as? Bar ,这实际上是switch语句所做的事情),而是设计足够多的类型,泛型方法和结构,从而无需进行可选的强制转换。 我邀请读者给出充分的理由,但是以下是针对这种特定情况的简要说明:您可能会轻易忘记实施已经定义的操作。

我提出的解决方案稍微简化了Redux图,因为它在每个动作中将reducer(现在称为mutator )实现为一种方法:

 公共协议ActionProtocol { 
关联类型状态
func mutate (_ state: inout State )->无效
}

但是,这不会更改功能。 减速器简单地由动作可变器代替:

请继续关注第二部分(即将推出),其中我将讨论一些实验功能,这些功能可能会在不久的将来添加到Swux中。

查看其余的代码,并随时进行协作或提出建议: https : //github.com/wircho/Swux