View 的最大的任务就是向 Controller 传递用户动作事件。
ViewController 不再承担一切代理和数据源的职责,通常只负责一些分发和取消网络请求以及一些其他的任务。

1.1 苹果推荐的 MVC -- 愿景

  • Cocoa MVC
    • 由于 Controller 是一个介于 View 和 Model 之间的协调器,所以 View 和 Model 之间没有任何直接的联系。Controller 是一个最小可重用单元,这对我们来说是一个好消息,因为我们总要找一个地方来写逻辑复杂度较高的代码,而这些代码又不适合放在 Model 中。
    • 理论上来讲,这种模式看起来非常直观,但你有没有感到哪里有一丝诡异?你甚至听说过,有人将 MVC 的缩写展开成 (Massive View Controller),更有甚者,为 View controller 减负也成为 iOS 开发者面临的一个重要话题。如果苹果继承并且对 MVC 模式有一些进展,所有这些为什么还会发生?

1.2 苹果推荐的 MVC -- 事实

  • Realistic Cocoa MVC
    • Cocoa 的 MVC 模式驱使人们写出臃肿的视图控制器,因为它们经常被混杂到 View 的生命周期中,因此很难说 View 和 ViewController 是分离的。尽管仍可以将业务逻辑和数据转换到 Model,但是大多数情况下当需要为 View 减负的时候我们却无能为力了,View 的最大的任务就是向 Controller 传递用户动作事件。ViewController 不再承担一切代理和数据源的职责,通常只负责一些分发和取消网络请求以及一些其他的任务。
    • 你可能会看见过很多次这样的代码:
          BookModel *bookModel = [myDataArray objectAtIndex:indexPath.row];
          [cell configWithModel:bookModel];
      • 这个 cell,正是由 View 直接来调用 Model,所以事实上 MVC 的原则已经违背了,但是这种情况是一直发生的甚至于人们不觉得这里有哪些不对。如果严格遵守 MVC 的话,你会把对 cell 的设置放在 Controller 中,不向 View 传递一个 Model 对象,这样就会大大减少 Controller 的体积。Cocoa 的 MVC 被写成 Massive View Controller 是不无道理的。
    • 直到进行单元测试的时候才会发现问题越来越明显。因为你的 ViewController 和 View 是紧密耦合的,对它们进行测试就显得很艰难--你得有足够的创造性来模拟 View 和它们的生命周期,在以这样的方式来写 View Controller 的同时,业务逻辑的代码也逐渐被分散到 View 的布局代码中去。

1.3 MVC 自身的不足

    • MVC 是一个用来组织代码的权威范式,也是构建 iOS App 的标准模式。Apple 甚至是这么说的。在 MVC 下,所有的对象被归类为一个 model,一个 view,或一个 controller。Model 持有数据,View 显示与用户交互的界面,而 View Controller 调解 Model 和 View 之间的交互。然而,随着模块的迭代我们越来越发现 MVC 自身存在着很多不足。
    • 1)MVC 在现实应用中的不足:
      • 在 MVC 模式中 view 将用户交互通知给控制器。view 的控制器通过更新 Model 来反应状态的改变。Model(通常使用 Key-Value-Observation)通知控制器来更新他们负责的 view。大多数 iOS 应用程序的代码使用这种方式来组织。
    • 2)愈发笨重的 Controller:
      • 在传统的 app 中模型数据一般都很简单,不涉及到复杂的业务数据逻辑处理,客户端开发受限于它自身运行的的平台终端,这一点注定使移动端不像 PC 前端那样能够处理大量的复杂的业务场景。然而随着移动平台的各种深入,我们不得不考虑这个问题。传统的 Model 数据大多来源于网络数据,拿到网络数据后客户端要做的事情就是将数据直接按照顺序画在界面上。随着业务的越来越来的深入,我们依赖的 service 服务可能在大多时间无法第一时间满足客户端需要的数据需求,移动端愈发的要自行处理一部分逻辑计算操作。这个时间一惯的做法是在控制器中处理,最终导致了控制器成了垃圾箱,越来越不可维护。
      • 控制器 Controller 是 app 的 “胶水代码”,协调模型和视图之间的所有交互。控制器负责管理他们所拥有的视图的视图层次结构,还要响应视图的 loading、appearing、disappearing 等等,同时往往也会充满我们不愿暴露的 Model 的模型逻辑以及不愿暴露给视图的业务逻辑。这引出了第一个关于 MVC 的问题...
      • 视图 view 通常是 UIKit 控件(component,这里根据习惯译为控件)或者编码定义的 UIKit 控件的集合。进入 .xib 或者 Storyboard 会发现一个 app、Button、Label 都是由这些可视化的和可交互的控件组成。View 不应该直接引用 Model,并且仅仅通过 IBAction 事件引用 controller。业务逻辑很明显不归入 view,视图本身没有任何业务。
      • 厚重的 View Controller 由于大量的代码被放进 viewcontroller,导致他们变的相当臃肿。在 iOS 中有的 view controller 里绵延成千上万行代码的事并不是前所未见的。这些超重 app 的突出情况包括:厚重的 View Controller 很难维护(由于其庞大的规模);包含几十个属性,使他们的状态难以管理;遵循许多协议(protocol),导致协议的响应代码和 controller 的逻辑代码混淆在一起。
      • 厚重的 view controller 很难测试,不管是手动测试或是使用单元测试,因为有太多可能的状态。将代码分解成更小的多个模块通常是件好事。
    • 3)太过于轻量级的 Model:
      • 早期的 Model 层,其实就是如果数据有几个属性,就定义几个属性,ARC 普及以后我们在 Model 层的实现文件中基本上看不到代码(无需再手动管理释放变量,Model 既没有复杂的业务处理,也没有对象的构造,基本上 .m 文件中的代码普遍是空的);同时与控制器的代码越来厚重形成强烈的反差,这一度让人不禁对现有的开发设计构思有所怀疑。
    • 4)遗失的网络逻辑:
      • 苹果使用的 MVC 的定义是这么说的:所有的对象都可以被归类为一个 Model,一个 view,或是一个控制器。就这些,那么把网络代码放哪里?和一个 API 通信的代码应该放在哪儿?
      • 你可能试着把它放在 Model 对象里,但是也会很棘手,因为网络调用应该使用异步,这样如果一个网络请求比持有它的 Model 生命周期更长,事情将变的复杂。显然也不应该把网络代码放在 view 里,因此只剩下控制器了。这同样是个坏主意,因为这加剧了厚重控制器的问题。那么应该放在那里呢?显然 MVC 的 3 大组件根本没有适合放这些代码的地方。
    • 5)较差的可测试性
      • MVC 的另一个大问题是,它不鼓励开发人员编写单元测试。由于控制器混合了视图处理逻辑和业务逻辑,分离这些成分的单元测试成了一个艰巨的任务。大多数人选择忽略这个任务,那就是不做任何测试。
      • 上文提到了控制器可以管理视图的层次结构;控制器有一个 “view” 属性,并且可以通过 IBOutlet 访问视图的任何子视图。当有很多 outlet 时这样做不易于扩展,在某种意义上,最好不要使用子视图控制器(child view controller)来帮助管理子视图。在这里有多个模糊的标准,似乎没有人能完全达成一致。貌似无论如何,view 和对应的 controller 都紧紧的耦合在一起,总之,还是会把它们当成一个组件来对待。Apple 提供的这个组件一度以来在某种程度误导了大多初学者,初学者将所有的视图全部拖到 xib 中,连接大量的 IBoutLet 输出口属性,都是一些列问题。

iOS-MVC设计模式不足的更多相关文章

  1. iOS中MVC设计模式

    在组织大型项目的代码文件时,我们常用MVC的思想.MVC的概念讲起来非常简单,就和对象(object)一样.但是理解和应用起来却非常困难.今天我们就简单总结一下MVC设计理念. MVC(Model V ...

  2. iOS 基于MVC设计模式的基类设计

    iOS 基于MVC设计模式的基类设计 https://www.jianshu.com/p/3b580ffdae00

  3. iOS - MVC 架构模式

    1.MVC 从字面意思来理解,MVC 即 Modal View Controller(模型 视图 控制器),是 Xerox PARC 在 20 世纪 80 年代为编程语言 Smalltalk-80 发 ...

  4. iOS——MVVM设计模式

    一.典型的iOS构架——MVC 在典型的MVC设置中,Model呈现数据,Vie呈现用户界面,而ViewController调节它两者之间的交互. 虽然View和View Controller是技术上 ...

  5. Xamarin简介与Xamarin支持MVC设计模式

    Create Native iOS, Android,Mac and Windows apps in C#. 官方网站:http://xamarin.com/ 使用武器 Run a C# app, g ...

  6. AngularJS_01之基础概述、设计原则及MVC设计模式

    1.AngularJS: 开源的JS框架,用来开发单一页面应用,以及数据操作频繁的场景:2.设计原则: ①YAGNI原则:You Aren't Gonna Need It! 不要写不需要的代码! ②K ...

  7. 谈谈JAVA工程狮面试中经常遇到的面试题目------什么是MVC设计模式

    作为一名java工程狮,大家肯定经历过很多面试,但每次几乎都会被问到什么是MVC设计模式,你是怎么理解MVC的类似这样的一系列关于MVC的问题. [出现频率] [关键考点] MVC的含义 MVC的结构 ...

  8. Java Web开发中MVC设计模式简介

    一.有关Java Web与MVC设计模式 学习过基本Java Web开发的人都已经了解了如何编写基本的Servlet,如何编写jsp及如何更新浏览器中显示的内容.但是我们之前自己编写的应用一般存在无条 ...

  9. MVC设计模式与三层架构

    三层架构分别是:表示层(Web层).业务逻辑层(BLL层)和数据访问层(DAL层). (1)表示层负责: a.从用户端收集信息 b.将用户信息发送到业务服务层做处理 c.从业务服务层接收处理结果 d. ...

  10. 传智播客JavaWeb day07、day08-自定义标签(传统标签和简单标签)、mvc设计模式、用户注册登录注销

    第七天的课程主要是讲了自定义标签.简单介绍了mvc设计模式.然后做了案例 1. 自定义标签 1.1 为什么要有自定义标签 前面所说的EL.JSTL等技术都是为了提高jsp的可读性.可维护性.方便性而取 ...

随机推荐

  1. 当获取相似数据时,使用不同方法调用不同sp,但是使用同一个方法去用IIDataReader或者SqlDataReader读取数据时需要判断column name是否存在。

    /// <summary> /// Checks clumn Name /// </summary> /// <param name="reader" ...

  2. 前端之CSS盒模型介绍

    css盒模型 css盒模型是css的基石,盒模型由content(主体内容),padding(补白,填充),border(边框),margin(外间距); 1.content: width:数值+单位 ...

  3. 【转】HashMap 和 HashTable 到底哪不同 ?

    2017/05/29 | 分类: 基础技术 | 2 条评论 | 标签: HASHMAP, HASHTABLE 分享到: 原文出处: 程序员赵鑫 HashMap和HashTable有什么不同?在面试和被 ...

  4. 《高性能MySQL》读书笔记之创建高性能的索引

    索引是存储引擎用于快速找到记录的一种数据结构.索引优化是对查询性能优化的最有效手段.索引能够轻易将查询性能提高几个数量级.创建一个最优的索引经常需要重写查询.5.1 索引基础 在MySQL中,存储引擎 ...

  5. 对话框窗口最大化盖住任务栏问题!OnGetMinMaxInfo,WM_GETMINMAXINFO

    http://hi.baidu.com/csacer/item/37cd6ac2dec18d360831c6a7 在写程序时,如果包含了标题栏,但是没有包含最大化按钮或者最小话按钮,那么人工用Show ...

  6. selenium-Python之定位下拉框选择

    1.通过select 进行定位下拉框 下拉框如图所示 通过代码定位 #通过index进行选择Select(driver.find_element_by_id("cardType") ...

  7. 技术大众化--10款无需编程的App DIY开发工具

    你有一个很棒的创意但不会编程怎么办?外包.合伙开发还是从零学编程?这里提供另外一种方式--使用无需编程的App DIY开发工具.DIY开发工具不仅节省了开发时间和资金,更为那些创意无限热爱应用的人提供 ...

  8. JSONP 跨域请求 - 获取JSON数据

    如何用原生方式使用JSONP? 下边这一DEMO实际上是JSONP的简单表现形式,在客户端声明回调函数之后,客户端通过script标签向服务器跨域请求数据,然后服务端返回相应的数据并动态执行回调函数. ...

  9. bootstrap历练实例: 基本胶囊式的导航菜单

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  10. Bootstrap历练实例:按钮组大小

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...