iOS 的 App 架构是 App 项目开始开发时重要的工作之一,确定一个优秀的架构,会使开发初期的效率极大的提高,并降低项目维护的难度和可读性,说白了就是降低耦合度,也就是说,所有App 的架构都是围绕“解耦”这个主题来说的。当然,项目的架构也是在项目的不断更新迭代中不断的加以完善的。
那iOS可用的架构有哪些呢?
MVC
MVC 是苹果官方推荐的架构,也是iOS开发当前最流行的架构。
MVC 架构的优点的优点主要有两个,就是代码总量少和简单易懂。代码总量少,就是基本上所有的逻辑代码和视图交互代码都集中在VC中,view和model分别负责显示和提供数据,代码分配遵循一定的规则。这样一来,架构的简单易懂,新人也能快速上手和很好的维护。
而MVC的缺点也是显而易见的,主要是由于view层和控制器层高度耦合造成的,主要会导致代码过于集中,大量的代码集中在VC中,它将处理处理交互、视图更新、布局、model数据的获取和修改、导航等几乎所有的操作。又使以检测功能为主的单元测试需要配合特定视图才能进行。高度耦合的逻辑结构使增加功能使需要格外小心,因为不仅可能需要修改大量原有代码,也会使VC中的代码更加臃肿。
model层过于简单、相对VC中的庞大代码,model只是定义几个属性,在.m文件中几乎没有代码。而将网络和存储层放在model中,其异步调用的API会使整个model层更加复杂。若是将网络层放在VC中,则耦合进一步加剧。
一言以蔽之,就是代码分配过于笼统,对于任何一个类或者结构体,只要不是数据或者视图,都会放在 VC 中,而VC耦合了视图和控制器,这可以说是VC天生的缺点。
MVCS
MVCS 其实是针对MVC的优化。S是Store,意为存储。把存储化代码从model和VC中拆分出来构成单独的文件,就是所谓的数据层。
之前提到过MVC中的网络层无处安放,按照MVCS的原则,也可以将网络层放在“S“这一层级中,毕竟网络请求也是活的数据,而有时候在API请求后,数据都要进行缓存和持久化处理,所以放在数据层中也比较合理。
将数据层拆分出来后,整个项目的代码分配会更加均衡。同时,以往在VC中难以进行的单元测试,也可以根据单独的数据层文件进行测试。总图来看,代码耦合度和测试难度有所降低,对整体架构的维护和扩展也起到了促进作用。
MVP
MVP 的全称是 Model-View-Presenter。它和MVC的相同点在于两者的Model从理论上讲应该完全一样。两者的不同在于,MVC的View和Controller耦合在VC中,而MVP的View是单独的View/Controller,Presenter也是单独的类。其中,MVP包括了UIView和UIViewController,它们持有Presenter作为变量。当接受到用户交互信息时,它会调用Presenter进行处理,也就是说,View 中不包含任何的业务逻辑代码,它只会将交互交给Presenter,并从Presenter中接受结果来更新自己。而Presenter负责业务逻辑,它是View和Model的桥接。它会根据View中的交互修改Model,或者根据Model的变化修改View。
这里要注意,因为View持有Presenter,所以Presenter中的View应该声明为weak,以避免循环引用。
与MVC相比,MVP的耦合度大大降低,代码分配更加合理,测试起来比较方便,整个架构的理解和上手难度也并不高。
但是MVP的缺点在于,View中的所有交互都要交给Presenter去处理,从而一旦项目功能增加了,View的代码和Presenter的代码都会增加。相比MVC在ViewController一个文件里直接解决,MVP的代码总量可能翻倍,这样App的维护成本和文件都会增大。
MVVM
MVVM相对于MVC来说增加了一个ViewModel的层级,ViewModel扮演着两个重要角色:
一是根据业务需求整个View层所需要的数据,使视图直接调用单个数据就能展示所要的效果。简单来说,ViewModel 就是为了视图展示而对model的数据进行包装
二是View的交互响应者,所有用户的交互都会传给ViewMode,ViewModel会依次更新视图层所需要的属性,同时修改Model层的数据,这里依靠的是属性观察或者响应式架构。
注意,在VideModel层中,绝对不能包含视图的任何类或结构体。
MVC、MVP、MVVM架构比较
MVC、MVP、MVVM着三种架构都是由模型层(M-Model)、视图层(V-View)和中间层(C/P/VM-Controller/Presenter/VideModel)构成。这里先从局部比较开始,分别比较这三部分的差异,再比较整体差异
模型层几乎相同,MVC、MVP、MVVM这三种架构的模型从理论上来说都是数据来源,没有什么不同
视图层在理论上都设计为被动,但是实际上略有不同。在实际开发中,MVC中的视图层与中间层高度耦合,几乎所有的操作都由ViewController一手包办。从理论上来说,MVC希望视图层就是单纯的UIView,或者UIViewController,只负责UI的更新和互动,不设计业务逻辑和模型更新。在实际开发中,MVP和MVVM的视图层实现了MVC的理论期望,即与中间层严格分离。MVP的View层是完全被动的,单纯的把交互和更新传递给中间层。而MVVM的视图层并不是完全被动的,它会监视中间层的变化,一旦产生变化,则视图层也会相应变化。
中间层的设计是三种架构的核心差异。从逻辑上讲,中间层的作用就是连接视图层和模型层,它们用于处理交互、接受通知和完成数据更新。MVC的中间层Controller持有视图和模型。主要起到封装和连接的作用,通过传递参数和实例变量来完成各种操作。
MVP的Presenter持有模型,在更新模型上与MVC的Controller角色一致。但它们不拥有视图,而是视图拥有中间层。中间层的工作流程是:从视图层接收交互传递->响应->向视图层传递响应指令->视图进行更新。全部操作必须全部手写完成。
NVVM的中间层ViewModel持有模型,在更新模型上与两者相同。它完全独立于视图,视图拥有中间层,通过绑定属性进行自动更新。全部操作由响应式逻辑框架自动完成。
总的来说,MVC的耦合度很高,代码分配最不合理,维护和扩展的成本最高。但是因为无需层级传递,所以代码总量很少,适合初学者理解和应用。MVP和MVVM相似,耦合度和代码分配都比较合理,比较容易实现高测试覆盖率。MVP的缺点是视图层需要将所有的交互传递给中间层,且要手动实现响应和更新,所以代码量远超过MVVM。MVVM在响应和更新上,通过响应式框架自动操作,大大精简了代码量;但是需要引入第三方响应式框架。同时,因为属性观察环环相扣,调用栈很大,所以调试起来比较痛苦。
MVC、MVP和MVVM都是以视图为驱动的架构,三种皆以用户交互和视图更新为主要服务目标。它们的共同缺点是没有涉及界面之间的跳转,即路由的涉及。涉及到路由设计的VIPER框架在下一篇文章中详细介绍。
网友评论