IOS APP 架构设计

本文探讨了iOS应用架构的各个方面,从Model-View-Controller(MVC)模式开始,详细介绍了MVC的组成部分、反馈回路以及构建、更新、测试等关键任务。文章进一步讨论了其他常见的设计模式,如MVVM、MVC+ViewState、Model-Adapter-View-Binder(MAVB)和Elm架构。每种模式都涉及到了如何处理模型、视图、状态管理和通信,以及各自的优缺点和测试策略。文章强调了分离模型层和视图层的重要性,以及如何通过不同架构模式提高代码的可测试性和可维护性。
摘要由CSDN通过智能技术生成

1,APP架构概述


1.1应用架构

App 架构是软件设计的一个分支,它关心如何设计一个 app 的结构。具体来说,它关注于两个 方面:如何将 app 分解为不同的接口和概念层次部件,以及这些部件之间和自身的不同操作中 所使用的控制流和数据流路径。

我们通常使用简单的框图来解释 app 的架构。比如,Apple 的 MVC 模式可以通过 model、 view 和 controller 三层结构来描述。

上面框图中的模块展示了这个模式中不同名字的三个层次。在一个 MVC 项目中,绝大部分的代 码都会落到其中某个层上。箭头表示了这些层进行连接的方式。

但是,这种简单的框图几乎无法解释在实践中模式的操作方式。这是因为在实际的 app 架构中, 部件的构建有非常多的可能性。事件流在层中穿梭的方式是什么?部件之间是否应该在编译期 间或者运行时持有对方?要怎么读取和修改不同部件中的数据?以及状态的变更应该以哪条路 径在 app 中穿行?

1.2Model 和 View

在最高的层级上,app 架构其实就是一套分类,app 中不同的部件会被归纳到某个类型中去。 在本书中,我们将这些不同的种类叫做层次:一个层次指的是,遵循一些基本规则并负责特定 功能的接口和其他代码的集合。

Model 层和 View 层是这些分类中最为常⻅的两个。

Model 层是 app 的内容,它不依赖于 (像 UIKit 那样的) 任何 app 框架。也就是说,程序员对 model 层有完全的控制。Model 层通常包括 model 对象 (在录音 app 中的例子是文件夹和录音对象) 和协调对象 (比如我们的 app 例子中的负责在磁盘上存储数据的 Store 类型)。被存储在 磁盘上的那部分 model 我们称之为文档 model (documentation model)。

View 层是依赖于 app 框架的部分,它使 model 层可⻅,并允许用戶进行交互,从而将 model 层转变为一个 app。当创建 iOS 应用时,view 层几乎总是直接使用 UIKit。不过,我们也会看 到在有些架构中,会使用 UIKit 的封装来实现不同的 view 层。另外,对一些其他的像是游戏这 样的自定义应用,view 层可以不是 UIKit 或者 AppKit,它可能是 SceneKit 或者 OpenGL 的某 种封装。

有时候,我们选择使用结构体或者枚举来表示 model 或者 view 的实例,而不使用类的对象。 在实践中,类型之间的区别非常重要,但是当我们在 model 层中谈到对象、结构体和枚举时, 我们会将三者统一地称为 model 对象。类似地,我们也会把 view 层的实例叫做 view 对象,实 际上它们也可能是对象、结构体或者枚举。

View 对象通常会构成一个单一的 view 层级,在这个层级中,所有的 view 对象通过树结构的方 式连接起来。在树的根部是整个屏幕,屏幕中存在若干窗口,接下来在树的分支和叶子上是更 多的小 view。类似地,view controller 也通常会形成 view controller 层级。不过,model 对 象却不需要有明确的层级关系,在程序中它们可以是互不关联的独立 model。

当我们提到 view 时,通常指的是像一个按钮或者一个文本 label 这样的单一 view 对象。当我 们提到 model 时,我们通常指的也是像一个 Recording 实例或者 Folder 实例这样的单个 model 对象。在该话题的大多数文献中,“model” 在不同上下文中指的可能是不同的事情。它 可以指代一个 model 层,model 层中的具体的若干对象,文档 model,或者是 model 层中不 关联的文档。虽然可能会显得啰嗦,我们还是会尝试在本书中尽量明确地区分这些不同含义。

为什么 Model 和 View 的分类会被认为是基础中的基础

当然啦,就算不区分 model 层和 view 层,写出一个 app 也是绝对可能的。比如说,在一个简 单的对话框中,通常就没有独立的 model 数据。在用戶点击 OK 按钮的时候,我们可以直接从 用戶界面元素中读取状态。不过通常情况下,model 层的缺失,会让程序的行为缺乏对于清晰 规则的依据,这会使得代码难以维护。

定义一个 model 层的最重要的理由是,它为我们的程序提供一个表述事实的单一来源,这会让 逻辑清晰,行为正确。这样一来,我们的程序便不会被应用框架中的实现细节所支配。

应用框架为我们提供了构建 app 所需要的基础设施。在本书中,我们使用 Cocoa - 或者更精确 说,根据目标平台,使用 UIKit,AppKit 或者 WatchKit - 来作为应用框架。

如果 model 层能做到和应用框架分离,我们就可以完全在 app 的范围之外使用它。我们可以很 容易地在另外的测试套件中运行它,或者用一个完全不同的应用框架重写新的 view 层。这个 model 层将能够用于 Android,macOS 或者 Windows 版本的 app 中。

1.3App 的本质是反馈回路

View 层和 model 层需要交流。所以,两者之间需要存在连接。假设 view 层和 model 层是被清晰地分开,而且不存在无法解耦的联结的话,两者之间的通讯就需要一些形式的翻译:

从根本上说,用戶界面是一个同时负责展示和输入功能的反馈设备,所以毫无疑问,这导致的 结果就是一个反馈回路。每个 app 设计模式所面临的挑战是如何处理这张图表中箭头所包含的 交流,依赖和变换。

在 model 层和 view 层之间不同的路径拥有不同的名字。用戶发起的事件会导致 view 的响应, 我们把由此引起的代码路径称为 view action,像是点击按钮或者选中 table view 中的某一行 就属于 view action。当一个 view action 被送到 model 层时,它会被转变为 model action (或 者说,让 model 对象执行一个 action 或者进行更新的命令)。这种命令也被叫做一个消息 (特别 在当 model 是被 reducer 改变时,我们会这么称呼它)。将 view action 转变为 model action 的操作,以及路径上的其他逻辑被叫做交互逻辑。

一个或者多个 model 对象上状态的改变叫做 model 变更。Model 的变更通常会触发一个

model 通知,比如说从 model 层发出一个可观测的通知,它描述 model 层中什么内容发生了 改变。当 view 依赖于 model 数据时,通知会触发一个 view 变更,来更改 view 层中的内容。 这些通知可以以多种形式存在:Foundation 中的 Noti?cation,代理,回调,或者是其他机制, 都是可以的。将 model 通知和数据转变为 view 更改的操作,以及路径上的其他逻辑被叫做表 现逻辑。

根据 app 模式的不同,有些状态可能是在文档 model 之外进行维护的,这样一来,更新这些状 态的行为就不会追随文档 model 的路径。在很多模式中的导航状态就这种行为的一个常⻅例 子,在 view 层级中的某个部分 (或者按照 Cocoa Storyboard 中使用的术语,将它称为 scene) 可能会被换出或者换入层级中。

在 app 中非文档 model 的状态被叫做 view state。在 Cocoa 里,大部分 view 对象都管理着它 们自己的 view state,controller 对象则管理剩余的 view state。在 Cocoa view state 的框图 中,通常会有加在反馈回路上的捷径,或者单个层自身进行循环。在有一些架构中,view state 不属于 controller 层,而是属于 model 层的部分 (不过,根据定义,view controller 并不是文 档 model 的一部分)。

当所有的状态都在 model 层中被维护,而且所有的变更都通过完整的反馈回路路径进行传递 时,我们就将它称为单向数据流。当任意的 view 对象或者中间层对象只能够通过 model 发出 的通知来进行创建和更新 (换句话说,view 或者中间层不能通过捷径来更新自身或者其他的 view) 时,这个模式通常就是单向的。

1.4架构技术

Apple 平台的标准 Cocoa 框架提供了一些架构工具。Noti?cation 将值从单一源广播给若干个 收听者。键值观察 (KVO) 可以将某个对象上属性的改变报告给另一个对象。然而,Cocoa 中的 架构工具十分有限,我们将会使用到一些额外的框架。

本书中使用到的第三方技术中包含了响应式编程。响应式编程也是一种用来交流变更的工具, 不过和通知或者 KVO 不同的是,它专注于在源和目标之间进行变形,让逻辑可以在部件之间传 输信息的同时得以表达。

我们可以使用像是响应式编程或者 KVO 这样的技术创建属性绑定。绑定接受一个源和一个目 标,无论何时,只要源发生了变化,目标也将被更新。这和手动进行观察在语法上有着不同, 我们不再需要写观察的逻辑,而只需要指定源和目标,接下来框架将会为我们处理其余部分的 工作。

macOS 上的 Cocoa 包含有 Cocoa 绑定技术,它是一种双向绑定,所有的可观察对象同时也是 观察者,在一个方向上建立绑定连接,会在反方向也创建一个连接。不论是 (在MVVM-C 的章

节中用到的) RxCocoa,还是 (MAVB 章节 中用到的) CwlViews,都不是双向绑定的。所以,在

本书中,所有关于绑定的讨论都只涉及到单向绑定。

1.5App 任务

要让程序正常工作,view 必须依赖于 model 数据来生成和存在,我

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值