您的位置:首页 > 运维架构 > 网站架构

业务组件架构的思考

2017-04-22 11:57 281 查看
在iOS开发中,我们接触比较多的是MVC架构,下面我们先来分析一下MVC架构。

1.MVC

  MVC是一种软件架构模式,在1978年由Trygve Reenskaug提出,它把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller):

视图(View):用户界面。

控制器(Controller):业务逻辑处理,协调所有的工作。它使数据从模型传出来然后显示在视图上,监听事件,在必要的时候操作数据。

模型(Model):用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。

1.1iOS中的MVC

  MVC是我们在客户端开发中最常见的模式,在iOS中,模型、视图、控制器之间的相互调用有一些规范和约定,借用斯坦福大学公开课第一课的一张截图,如下所示:



  对于上图的理解,有如下几点:

先说明一下上图中的三种线:黄色实线、白色实线、白色虚线。可以看到,Model和View之间是两条黄色实线,这表示不能穿越这黄线,任何一个方向都不行,即Model和View完全分离。白色虚线表示可以自由的穿越它,只要是安全的。白色实线表示可以穿越,但需要交过路费。

绿色的箭头表示直接引用。简单的说,就是包含引用类的头文件和类的实例变量。上图中只有 Controller 中,有对 Model 和 View 的直接引用。

View对Controller的通信有三种方式:Target-Action(如按钮的点击事件)、delegate(如表格的UITableViewDelegate)、data source(如表格的UITableViewDataSource)。通过这三种方式,View 达到了既能向 Controller 通信,又不需要知道具体的 Controller ,从而达到解耦的目的。

Model 主要是通过 Notification 和 KVO 来和 Controller 通信的。

1.2MVC的优点

低耦合和高重用性。View和Model完全隔离,这样我们既可以很容易让同一套Model来适配不同的View(比如同时做iPad版和iPhone版),也可以很容易让多套Model在同一个View上展现(比如说根据数据源不同显示表格)。

可维护性。各层分离,使得应用更易于维护和修改。

1.3MVC的缺点

  上图介绍的MVC是一种理想化的MVC,在我们实际项目中,MVC常常是这样的:



  在iOS的项目开发中,View和Controller分的并不是特别清楚,导致写出臃肿的ViewController,最终让人感觉不是MVC,而是Model+ViewController。出现这种情况是为什么呢?这是因为UIViewController中自带了一个View,且控制了View的整个生命周期(viewDidLoad,viewWillAppear...)。自带的这个View,不光可以展示视图,更主要的任务是作为一个容器,来添加别的视图。

1.4怎样划分MVC的职责?

  MVC是最基本的架构,在MVC的规范下,可以演化出其他的各种架构,如对胖Controller的拆分成MVCS,拆分胖Model成MVVM等等。不管怎么拆分,一定符合MVC规范。这里先继续介绍怎样划分MVC的职责,能比较好的规避臃肿ViewController的问题。

Model的职责

给Controller提供数据;

给Controller存储数据;

提供业务基本组件(可以这样来理解基本组件:把Controller里面的私有方法单独封装出来),供Controller调用。

View的职责

显示页面视图;

响应与业务无关的事件,比如说动画效果、视图更新等等。

Controller的职责

管理视图容器的生命周期;

负责生成所有的View实例,并放入视图容器;

监听来自View与业务有关的事件,通过与Model的合作,来完成对应事件的响应。

1.5MVC小结

从上面的分析,我们可以看到:MVC是一种很优秀的架构,但它也存在一些问题,最大的问题是导致写出臃肿的ViewController,当前我们的做法是引入了一个DataHelper类来分解一部分VC里面的职能。有没有其他的方案呢?我们继续来分析。

2.MVVM

MVVM,Model-View-ViewModel,一个从 MVC 模式中进化而来的设计模式,最早于2005年被微软的 WPF 和 Silverlight 的架构师 John Gossman 提出。在 iOS 开发中实践 MVVM 的话,通常会把大量原来放在 ViewController 里的视图逻辑和数据逻辑移到 ViewModel 里,从而有效的减轻了 ViewController 的负担。另外通过分离出来的 ViewModel 获得了更好的测试性,我们可以针对 ViewModel 来测试,解决了界面元素难于测试的问题。MVVM 通常还会和一个强大的绑定机制一同工作,一旦 ViewModel 所对应的 Model 发生变化时,ViewModel 的属性也会发生变化,而相对应的 View 也随即产生变化。

2.1MVVM介绍

面向协议的 MVVM 架构介绍

Introduction to MVVM

2.2MVVM的优点

减轻了VC的负担;

提高了可测试性;

强大的绑定机制。

2.3MVVM的缺点

学习成本和开发成本较高;

数据绑定使得BUG更难调试;

VM的职责过重。

3.MVVMWithDC

3.1View和ViewController



每一个View都有一个与之对应的ViewModel,View的数据展示和样式都由它确定;

不引入双向绑定机制和观察机制,而是通过传统的代理回调或通知将UI事件传给ViewController;

ViewController只负责将ViewModel装配给View,接受UI事件。

这样做的优点是:

View可以完全解耦,只要确定好ViewModel和回调接口;

ViewController可以尽可能少的和View的具体实现打交道,将这部分职责转给了ViewModel,降低了ViewController的负担;

使用传统的代理回调和通知方式,学习成本低,降低了维护和调试的成本。

3.2ViewController和Model



将获取数据和处理数据的职责从传统MVVM的VM中抽离出来,成为DataController;

VC请求数据或修改数据的UI事件传递给DC来处理;

DC接收到数据请求后,向DataRequest获取数据或修改数据,并使用Model包装,返回给VC。

这样做的优点是:

避免了传统MVVM的VM过于臃肿的问题,另外模块的职责更清晰;

业务逻辑解耦,数据的加工和处理放在DC,VC不关心数据的获取和加工;DC不关心页面的展示和交互;

3.3完整的架构图



3.3.1优点

层次清晰,职责明确:和界面有关的逻辑完全划到 ViewModel 和 View 一遍,其中 ViewModel 负责界面相关逻辑,View 负责绘制;DataController 负责页面相关的数据逻辑,而 Model 还是负责纯粹的数据层逻辑。 ViewController 仅仅只是充当简单的胶水作用。

耦合度低,测试性高:除开 ViewController 外,各个部件可以说是完全解耦合的,各个部分也是可以完全独立测试的。同一个功能,可以分别由不同的开发人员分别进行开发界面和逻辑,只需要确立好接口即可。

复用性高:解耦合带来的额外好处就是复用性高,数据逻辑代码不放在 ViewController 层可以更方便的复用。

学习成本低: 本质上来说,这个架构属于对 MVC 的优化,主要在于解决 Massive View Controller 问题,把原本属于 View Controller 的职责根据界面和逻辑部分相应的拆到 ViewModel 和 DataController 当中,所以是一个非常易于理解的架构设计,即使是新手也可以很快上手。

开发成本低: 完全不需要引入任何第三方库就可以进行开发,也避免了因为 MVVM 维护成本高的问题。

实施性高,重构成本低:可以在 MVC 架构上逐步重构的架构,不需要整体重写,是一种和 MVC 兼容的设计。

3.3.2缺点

当页面的交互逻辑非常多时,需要频繁的在 DC-VC-VM 里来回传递信息,造成了大量胶水代码。

另外,由于在传统的 MVVM 中 VM 原本是一体的,一些复杂的交互本来可以在 VM 中直接完成测试,如今却需要同时使用 DC 和 VM 并附上一些胶水代码才能进行测试。

没有了 Binding,代码写起来会更费劲一点。

3.3.3代码

GofArchDemo

3.4参考资料

猿题库 iOS 客户端架构设计

4.总结

每个业务的需求不一样,难度和业务场景都不一样,因此在选择业务组件架构的时候,个人认为应该是根据需要进行合理的安排业务组件的架构。原则上如果业务很简单,那么使用MVC即可,毕竟MVC架构层次清晰,类结构也简单,对于业务复杂度较低的,没必要使用MVVM或者更深层次的架构,来人为的增加复杂度。

这里给一个参考标准:如果使用MVC架构,Controller的代码行数超过500行,那么可以考虑使用MVVM或者其他架构来分化Controller的部分职责。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: