iOS 常见架构一览

最近团队又在撕逼iOS 项目的架构选型问题,虽然最后MVVM携易测试和易使用的优势取胜,总觉得这个话题意犹未尽,值得再聊一聊。

在进入主题之前,我们先来看看架构的目标,

架构的目标是解决利益相关者的关注点, 让系统达到易理解,易维护,易扩展,易测试,成本可控等特点。

在设计演化架构的过程中,对于一些广为人知的原则(Best Practice)要结合考虑, 如:

  • 单一职责原则:一个实体应尽量少地与其他实体之间发生相互作用,应该使得功能模块相对独立,做到低耦合,高内聚。
  • 开闭原则:是指对扩展开放,对修改封闭。程序应该具有良好的扩展性,主要依靠接口和抽象类,使程序易于维护和升级。
  • 接口隔离原则:使用多个隔离的接口,比使用单个庞大的接口要好。有利于降低耦合,易于维护升级。

常见的还有组合复用原则,最少知识原则, 里氏替换原则等。

一般移动应用中,都包括ViewModel 组件,由于View 和 Model 之间高度耦合,禁止直接相互操作,需要通过Controller、ViewModel、Presenter等方式桥接,也就带来了多种多样的架构设计。

历史

MVC最初在Smalltalk语言中被发明出来,后来者苹果公司的Cocoa中广泛使用并提出了Apple MVC框架。 MVC的实践者还有WebObjects, Ruby on Rails, �和 Django等。

Martin Fowler 在2004年提出了�MVP作为MVC的替换者,Presentation Model和视图控制无依赖,并呈现应用的状态和视图的行为。

MVVM是在MVP的基础上添加了数据绑定的概念,让数据和视图同步更加简单。

Apple MVC

iOS 常见架构一览_第1张图片

MVC作为苹果在iOS开发上前期主推的架构,结构简单,容易上手, 前期开发效率高。

让View的归View,Model的归Model,其他的Controller一肩挑起。

注意View 和 Model这里都是很薄的,Model类似于Java中的POJO对象, 只定义属性和Setter/Getter方法。

但由于没有清晰描述业务逻辑,网络请求,数据转换等代码的位置,�容易引起很多问题:

  • 大量业务逻辑堆砌在Controller组件内,导致代码臃肿,难以维护,无论添加和修改代码,都让后来者难以下手。
  • 逻辑代码耦合度低,相互纠缠,单元测试难以开展。
  • 开发者习惯不一,增加团队成员之间代码阅读的复杂度。

�当然也可以在MVC的基础上,通过单一职责和接口隔离原则,把非生命周期和胶水行代码移出Controller,但这已经超出了MVC架构的范围,这里不做讨论。

MVVM

iOS 常见架构一览_第2张图片

和MVC对比,MVVM解决了Controller臃肿的问题,将逻辑代码、网络请求等都写入了ViewModel中,但需注意ViewModel过于臃肿的问题。

ViewModel为指定的View服务,ViewModel中包含了所有的展示逻辑, 且不依赖于View,让测试更容易进行。

MVVM别名 Model–View–Binder,数据绑定可以让开发者摆脱写View和Model之间业务状态同步代码的繁重工作。

MVVM是随着移动应用开发不停发展后出现的,是最流行/成功的架构, Google在2015年 I/O 大会上介绍给广大开发者的,并且在Android SDK层面上给予了支持,iOS开发者敞开怀抱支持吧。

iOS 常见架构一览_第3张图片
Android MVVM 架构图

多注意上图中的Repository 和 LiveData组件。

有兴趣的可以看看Google的官方例子,在iOS开发中可以参考借鉴。

MVP

iOS 常见架构一览_第4张图片

对比MVVM 和 MVP 的架构图,可以看出两者颇为类似。在两者中View不直接使用Model,它们之间的通信是通过Presenter/ViewModel 来进行的,所有的交互都发生在内部,

但上图中的View是被动的(Passive),Presenter与具体的View是没有直接关联的,而是通过定义具体的接口进行交互,从而在变更View时候可以保持Presenter的不变,达到Presenter重用。

由于通过接口进行交互,我们可以轻松模拟View的事件,从而实现对Presenter单元测试,这也是接口隔离带来的福利, 当然冗余的代码量也是不可避免的。

Redux - Like

iOS 常见架构一览_第5张图片

熟悉JS的人对 Redux 应该不会陌生,照搬了Stores, Reducers和 Actions等专有名词,模式上照搬了Redux的设计思路。

一个iOS应用本质上就是一个状态机,例如:从一个状态的视图由用户事件Action或者网络请求返回的数据Action触发达到下一个状态的视图。

细心地童鞋可能发现,上图中的数据流是单向的,是由数据驱动的。

iOS 常见架构一览_第6张图片

更多参看ReSwift 开源项目和样例

VIPER

iOS 常见架构一览_第7张图片

从架构图中可以看出VIPER比MPV更进一步,把层次分的更加明确,模块功能更单一(单一责任原则),更加方便测试。

  • Interaction 关于数据和网络请求的业务逻辑,例如从服务器/本地缓存中获取一些数据。
  • Entity 就是普通的数据对象,轻Model。
  • Router处理一个视图到另一个视图的导航,需要初始化所有其他类。

这里可以思考一下:为什么Router 在VIPER里是必要的,而在MVVM里不是必须的?

最后

架构本无好坏高下之分,只是适应了不同的场景孕育而生,是解决问题的工具,其实很多项目中都存在不同架构的混合使用的现象。

在实际项目中,莫要盲目追求‘高级’的架构,也不存在一个架构可以解决所有问题,结合实际需求和团队情况,选择适合自己的框架,逐步升级迭代,才能降低项目失败的风险。

更多

MVP WIKI
MVVM WIKI

请关注豆志昂扬微信公众号获取更多内容:

  • 扫描下图二维码;
  • 直接添加公众号豆志昂扬
iOS 常见架构一览_第8张图片

你可能感兴趣的:(iOS 常见架构一览)