ChrisEidhof,MattGallagher,FlorianKugler著王巍,茆⼦君,李杰译使⽤Swift进⾏iOS架构
英文版本 1.0 (2018 年 5 月),中文版本 1.0.1 (2018 年 7 月)
© 2018 Kugler und Eidhof GbR
版权所有
ObjC 中国
在中国地区独家翻译和销售授权
获取更多书籍或文章,请访问 https://objccn.io
电子邮件: mail@objccn.io
关于本书 5
1 介绍
应⽤架构 13
Model和 View 13
App的本质是反馈回路 15
架构技术 16
App任务 17
2
App 设计模式概览
Model-View-Controller 19
Model-View-Controller+ViewState 26
Model-View-ViewModel+协调器 22
Model适配器-View绑定器 (MAVB) 28
Elm架构 (TEA) 31
⽹络 34
没有提到的模式 34
3
4
Model-View-Controller
探索实现 39
测试 51
讨论 55
改进 56
总结 68
Model-View-ViewModel+协调器 (MVVM-C)
探索实现 73
测试 88
讨论 91
较少响应式编程的 MVVM 92
经验和教训 97
13
19
38
71
5 网络
⽹络挑战 101
Controller持有⽹络 102
Model拥有⽹络 107
讨论 112
6
7
8
Model-View-Controller+ViewState
将 View State作为 Model的⼀部分 115
探索实现 118
测试 131
讨论 136
经验和教训 138
Model 适配器-View 绑定器
探索实现 147
测试 163
讨论 168
经验和教训 172
Elm 架构
探索实现 179
Elm架构框架 191
测试 197
讨论 202
经验和教训 204
101
115
146
178
关于本书
本书所专注的话题是 app中所使⽤的架构,也就是那些将较⼩部分组合在⼀起形成⼀个完整
app时所使⽤的结构和⼯具。通常来说,⼀个 app会包含⾮常多种类的部件,像是⽤⼾输⼊、
⽹络服务、⽂件服务、⾳频和图像、以及窗⼝服务等等。在 app开发中,如何对它们进⾏架构
是⼀个很重要的话题。想要将这些部件组合起来,同时保证它们的状态以及状态的变更稳定可
靠,⽽且能正确地进⾏传递,并⾮⼀件易事。这需要⼀套有⼒的规则,来定义组件之间相互协
作的⽅式。
App 设计模式
我们将⼀组被重复使⽤的设计规则称为设计模式。本书将会展⽰如何使⽤五种最主要的 app设
计模式来完整实现⼀个 app。我们所挑选的模式中,有的已经经过⼴泛的验证,有的还处于实
验阶段,它们分别是:
→ Model-View-Controller (MVC)
→ Model-View-ViewModel+Coordinator (MVVM-C)
→ Model-View-Controller+ViewState (MVC+VS)
→ ModelAdapter-ViewBinder (MAVB)
→ Elm架构 (The Elm Architecture, TEA)
译者注:相较于 “模型-视图-控制器”,对于三者连接在⼀起所组成的架构名称,我们
更倾向于保留被⼴泛接受的原⽂,也即 Model-View-Controller的说法。但是,像是
协调器 (coordinator),适配器 (adapter),绑定器 (binder)等⽇常不太常⽤的词语,在
上下⽂清晰的环境下,我们会选择使⽤中⽂译名。
抽象的框图往往被⽤来在最⾼层级描述设计模式的使⽤⽅式,但是它对这些模式在 iOS app中
应该如何具体使⽤并没有太多帮助。我们之后将会详细研究每种架构的典型框图,并探讨它们
在实践中的使⽤⽅式。
在本书中,我们还会看到⼀系列不同的模式,在书写程序时,并没有哪个单独的模式能在所有
情景下都做到最好。根据你、你的程序或者你的团队所想要达成的⽬标和期望,以及整个过程
中所⾯临的的约束,任何⼀种模式都有可能是最佳选择。App的设计模式不仅仅只是⼀套技术
上的⼯具,它同时也是审美和社交的⼿段,可以让你,以及你的代码的其他读者,与你所设计
的程序产⽣交流。换⾔之,最好的模式就是对你来说最为清晰的模式。
架构技术和经验教训
展⽰每⼀种实现⽅式之后,我们会花⼀些时间讨论这种模式在解决问题时的优势,以及使⽤类
似策略在其他任意模式中解决问题的⽅式。⽐如说,像是 reducer,响应式编程,接⼝解耦,状
态枚举和多模型抽象这些技术,往往是和特定的模式绑定的。但是在本书中,在我们研究这些
技术在它们各⾃的模式中的使⽤⽅式之后,我们还会继续讨论它们的核⼼思想,看看这些思想
是如何跨越不同的模式来解决问题的。
本书将会为你展⽰,对于每个问题,app的架构包含了多种解决⽅案。当被正确实现后,所有
的解决⽅案最终都将为⽤⼾呈现出同样的结果。这也就是说,app架构的选择所关乎到的是我
们程序员⾃⼰的幸福。我们想要在背后解决的潜在问题是什么?我们需要个别单独考虑的问题
⼜有哪些?我们在何处需要⾃由度?⼜在何处需要稳定性?我们在哪⾥需要抽象?我们⼜在哪
⾥需要简化?通过⼀次次地思考这些问题,我们对使⽤的架构进⾏选择。
关于录音 App
在本书中,我们会展⽰同⼀个录⾳ app的五种不同实现。所有实现的完整源码都公开在
GitHub上,您可以随时参阅。这个录⾳ app正如其名,它可以记录和播放语⾳笔记。我们可以
在 app⾥以⽂件夹的⽅式组织记录的语⾳。这个 app主要由⽤于组织⽂件的可以导航的
FolderViewController,⽤于播放⽂件的 PlayViewController,⽤于记录新⽂件的以 modal⽅
式显⽰的 RecordViewController,以及⼀个⽤来命名⽂件和⽂件夹的⽂本对话框组成。所有的
内容都以标准的 UIKit master-detail界⾯⽅式进⾏展⽰,其中 FolderViewController位于主
栏,PlayViewController位于副栏进⾏显⽰。
在选择本书的⽰例 app时,我们列了⼀个判断标准,录⾳ app满⾜了表⾥的所有项⽬。对于展
⽰架构模式来说,它⾜够复杂;⽽放到⼀本书中时,它⼜⾜够简单。app中存在导航关系,其
中的⼀些视图是实时更新的,⽽不像很多 app中那样只存在静态视图。对模型层,我们实现了
持续化的存储,每个变更都会被⾃动保存到磁盘。我们还为其中的两个版本加上了⽹络的⽀持。
这个 app对 iPhone和 iPad都做了适配,最后,我们还⽀持冷启动的状态恢复。
如果我们选择⼀个规模更⼩的 app,书⾥的内容会更容易被理解,但是这样⼀来,我们就很难
有机会来展⽰各个架构之间的不同了。如果我们选择的 app规模再⼤⼀些,每种架构在可扩展
性⽅⾯的差距将显⽽易⻅,但是其中的细节也将被湮没。我们的录⾳ app恰到好处地在两个极
端之间做到了平衡。
App开始时会显⽰⼀个根⽬录的 FolderViewController。这个 controller存在于⼀个
navigation controller (导航控制器)中,⽽这个 navigation controller⼜是⼀个 split view
controller的 master controller。在 iPhone上,这个 controller将以全屏模式被展⽰,⽽在
iPad上,它将会被显⽰在屏幕左侧 (这是 iOS上 UISplitViewController的标准⾏为)。
⼀个⽂件⼰可以包含具体的录⾳⽂件以及其他的⽂件夹。FolderViewController允许我们添加
新的⽂件夹和录⾳,或者删除已有的项⽬。
在添加⽂件夹时,我们通过弹窗来询问⽂件夹的名字,⽽添加录⾳的操作将会直接展⽰⼀个
RecordViewController。