MVC = Massive View Controller ?

有笑话称MVC为重量级的试图控制器。仔细一想,确实存在这个问题。以UITableViewController和UITableView举个例子。 
一般情况下,我们没有必要创建一个自定义的tableview继承自UITableView。这意味着View的模块几乎为空白。(在相当多的时候,view也仅是一个xib文件或者一堆代码用来描述控件外观和控件的位置而已)。至于Model,十分类似于JavaBean,一个类,若干属性和constructor足矣。而大量的业务逻辑的处理被放在View Controller中。

MVC的目的与不足

最初我们希望,能够把视图、模型分离开来,并用一个视图控制器去管理两者。然而,理想很丰满,现实很骨感。实际编程时,遇到种种奇奇怪怪的情况。 
例如:

  1. 涉及到网络请求放在哪里?
  2. 数据逻辑的转换放在哪里?比如把一个NSArray类型的数组转换成NSString对象并且展示出来。

要知道,视图控制器,是用来管理视图的。让它处理这些乱七八糟的逻辑,是不是显得太臃肿了,管了太多自己不应该负责的事情。 
更何况,几乎所有的视图和视图控制器都是一一对应关系。既然视图离不开控制器,控制器也必须维护一个自己管理的视图,为什么不干脆把他们结合在一起?

新的设计结构——MVVM

简单来说。MVVM就是一个经过优化的MVC,这意味着它可以兼容,也本质上还是一个MVC结构。 
所谓的MVVM架构,就是把那些Controller不应该负责的内容分离出来。单独作为一块。用MVVM的术语来说,就是把“将 Model 数据转换为 View 可以呈现的东西”这一可能极为复杂的过程剥离出来,放到ViewModel对象中。至于ViewController,嗯,你就负责管好你的视图吧。别的东西你也别负责了。(因此,网络请求也应该被剥离开来,放入ViewModel中,实际上一次网络请求,只不过是将一些不在本机存放的模型,从Json转换为可供View直接展示的数据)。 
不管是从字面(ViewModel)还是从它的具体功能以及实现来理解,视图模型(ViewModel)依然是一个模型(Model),它为View提供了可以拿来使用的数据,也从模型(Model)提取数据并加以转化处理。

以一个简单的链状结构表示MVVM架构就是 
View/ViewController ————> ViewModel ————> Model 
这里ViewController对象直接持有一个ViewModel对象。ViewModel对象又直接持有Model对象。箭头不能被反向(这是MVVM架构的基本要求)。 
这样导致了一个问题,ViewModel发生变化的时候怎么通知ViewController并且相应的改变View呢?这就是ReactiveCocoa框架要干的事情了。Model的变化怎么通知ViewModel呢?额。。。。。Model需要变么?额。。。一定非得要变的话,继续用ReactiveCocoa不就行了么。

ReactiveCocoa是何方神圣?

以C语言代码举个例子

    int a = 1;
int b = 2;
int c = a + b;
printf("c = %d",c);

显然输出结果是“c = 3”。 
如果改变一下代码,增加一行。

    int a = 1;
int b = 2;
int c = a + b;
a++;
printf("c = %d",c);

显然输出结果依然是“c = 3”。 
如果我们希望c永远等于a和b的和,注意是永远等于。那么目前看来唯一的方法是每次a和b发生变化的时候重新执行c = a + b。这样的操作麻烦透了,幸运的是,iOS开发中,OC提供了KVO机制,而ReactiveCocoa框架利用了这个机制,并且进行了各种各样的拓展。

ReactiveCocoa框架有多强?

简单来说,试想一下:一个电路中有电源、开关,还有若干个小灯泡串联在一起。断开开关,所有的灯泡直接熄灭,多么简单的一件事!因为所有灯泡的亮暗直接依赖于开关的状态。而十个人居住在十个房间里,某个人起床时必须挨个通知其他九人:“我起床了”。What the huck?

举一个实际开发的例子。假设有一个注册界面,只有当输入的用户名密码满足某种逻辑的时候,注册按钮才会变为可用状态。通常我们需要实现文本框的代理函数,对于每一次文字变动,执行判断函数再去修改按钮的状态。

在ReactiveCocoa这种动态的、响应式框架下,我们要做的,就是把button的enabled属性和username.isValid && password.isValid绑定起来就可以了。

这样的逻辑实在是太棒了,在下一章中,我们一起探索ReactiveCocoa框架的实际使用。

mvvm 模式的更多相关文章

  1. MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息

    MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二 ...

  2. MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信

    MVVM模式解析和在WPF中的实现(五) View和ViewModel的通信 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 M ...

  3. MVVM模式解析和在WPF中的实现(三)命令绑定

    MVVM模式解析和在WPF中的实现(三) 命令绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  4. MVVM模式和在WPF中的实现(二)数据绑定

    MVVM模式解析和在WPF中的实现(二) 数据绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  5. MVVM模式和在WPF中的实现(一)MVVM模式简介

    MVVM模式解析和在WPF中的实现(一) MVVM模式简介 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在 ...

  6. [转载]MVVM模式原理分析及实践

    没有找到很好的MVVM模式介绍文章,简单找了一篇,分享一下.MVVM实现了UI\UE设计师(Expression Blend 4设计界面)和软件工程师的合理分工,在SilverLight.WPF.Wi ...

  7. dynamic-css 动态 CSS 库,使得你可以借助 MVVM 模式动态生成和更新 css,从 js 事件和 css 选择器的苦海中脱离出来

    dynamic-css 使得你可以借助 MVVM 模式动态生成和更新 css,从而将本插件到来之前,打散.嵌套在 js 中的修改样式的代码剥离出来.比如你要做元素跟随鼠标移动,或者根据滚动条位置的变化 ...

  8. mvc mvp mvvm模式的区别

    mvc模式中,Model不依赖于View,但是View是依赖于Model的,m和v没有进行完全的分离,三者之间是单向的操作 mvp模式中,m和v之间的交互是双向的,m和v完全分离,m和v的交互是通过P ...

  9. 转:界面之下:还原真实的 MVC、MVP、MVVM 模式

    前言 做客户端开发.前端开发对MVC.MVP.MVVM这些名词不了解也应该大致听过,都是为了解决图形界面应用程序复杂性管理问题而产生的应用架构模式.网上很多文章关于这方面的讨论比较杂乱,各种MV*模式 ...

  10. 由项目浅谈JS中MVVM模式

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.    背景 最近项目原因使用了durandal.js和knock ...

随机推荐

  1. 酒鬼-DP

    Description Santo刚刚与房东打赌赢得了一间在New Clondike 的大客厅.今天,他来到这个大客厅欣赏他的奖品.房东摆出了一行瓶子在酒吧上.瓶子里都装有不同体积的酒.令Santo高 ...

  2. android + javascript 相互通信实例分析

    1.  AndroidManifest.xml中必须使用许可 "android.permission.INTERNET", 否则会出Web page not available错误 ...

  3. iosiOS 地图 自定义以及添加锚点

    - (void)clickLongPress:(UILongPressGestureRecognizer *)longPress { CGPoint point = [longPress locati ...

  4. SVN与TortoiseSVN实战:从入门到精通

    SVN,版本控制程序,是支撑项目开发的基础工具. 在团队开发中,不管是程序员还是美工.测试等人员,都会用到SVN,通常会把SVN视为源代码管理工具,但对于SVN更准确的理解是: “帮助参与项目人员的管 ...

  5. 第四章_PHP基本语法(2)

    1.常量的声明 在PHP中,定义常量使用define()函数来实现 2.魔术常量 名称 作用 __LINE__ 返回文件中的当前行号 __FILE__ 返回该文件的完整路径和文件名 __DIR__ 返 ...

  6. 用IKVMC将jar转成dll供c#调用

    用IKVMC将jar转成dll供c#调用 ikvmc c# dll jar 用IKVMC将jar转成dll供c#调用 前言 ikvmc介绍 ikvmc下载安装 下载并解压 设置环境变量 jar-> ...

  7. 关于javascript 里面类型的判断

    javacript至今共有7中类型 Six data types that are primitives: Boolean Null Undefined Number String Symbol (n ...

  8. linux中的虚拟化网络模型及各种模型实现

    第一种隔离模型: Guest1和Guest2都为虚拟机. 首先要了解在linux中的虚拟机的网卡都包含前半段和后半段,前半段在虚拟机上,后半段在宿主机上,这里以centos6为例,上图 eth0为Gu ...

  9. linux shell 逻辑运算符、逻辑表达式

    shell的逻辑运算符 涉及有以下几种类型,因此只要适当选择,可以解决很多复杂的判断. 一.逻辑运算符  逻辑卷标 表示意思 1. 关于档案与目录的侦测逻辑卷标! -f 常用!侦测『档案』是否存在 e ...

  10. (转)Android属性设置android:noHistory="true"

    设置 android:noHistory="true"后,该Activity在statck中不留历史痕迹.默认的值是false. 举例说明,假设有三个Activity分别是:A,B ...