MYDay-第1期-Introduction to MVC-MVVM for iOS

Preface


首先,感谢一下老师和朋友们对我一直以来的支持以及宽容。最近,我所实习的公司开办了一个名为 MY Day 的内部技术分享活动,作为活动的组织者之一及第一期的分享嘉宾,我倍感荣幸,但同时也压力山大。考虑到公司新来实习的同学们基础不同,思来想去,第一期还是分享一些基础的知识,目的是参与的人能够听懂,并提出一些比较好的问题,希望起到抛砖引玉的作用。内容不新鲜,希望大家批评指正,多多包容,感谢!

What is MVC


MVC全称是Model View Controller,是模型 (model)-视图 (view)-控制器 (controller) 的缩写。它表示的是一种常见的客户端软件开发框架。MVC 的概念最早出现在二十世纪八十年代的 施乐帕克 实验室中(对,就是那个发明图形用户界面和鼠标的实验室),当时施乐帕克为 Smalltalk 发明了这种软件设计模式。
现在,MVC 已经成为主流的客户端编程框架,在 iOS 开发中,系统为我们实现好了公共的视图类:UIView,和控制器类:UIViewController。大多数时候,我们都需要继承这些类来实现我们的程序逻辑,因此,我们几乎逃避不开 MVC 这种设计模式。

How MVC work


总的来说,视图(view)传送指令到Controller,Controller完成业务逻辑后,依赖指令去选择加载某个Model或要求Model改变状态,Model将新的数据发送给view,view更新数据,用户得到反馈。


MYDay-第1期-Introduction to MVC-MVVM for iOS_第1张图片
  • 视图(View):实现数据有目的的显示,通常是一个用户界面元素。在视图中一般没有程序上的逻辑。在Web应用中的MVC,通常把显示动态数据的html页面称之为视图。
  • 视图控制器(Controller):处理和响应事件,通常是用户操作,并监控模型上的变化,然后去修改数据。
  • 模型(Model):模型用于封装与应用业务逻辑相关的数据及对相关数据的处理方法,模型不关心自己会被如何调用、如何显示、如何操作。

How to communicate between M-V-C


该部分图片及内容来自斯坦福大学公开课,我认为他就 iOS 方面的MVC的通信的描述,还是比较好的。内容概括为以下几点:

MYDay-第1期-Introduction to MVC-MVVM for iOS_第2张图片
communications
1、Between Controller and View
  • Controller通过outlet "出口"持有view
  • View上的action目标动作会反馈到Controller对应的target上
  • View的没一个action动作,都会通过delegate代理反馈给Controller,包括will、did、should等,意思是将要/已经/正在进行动作
  • View需要Controller为之解释模型
  • View上需要的数据,通过View和Controller之间的dataSource数据源获得
  • Controller和View之间采用blind structured way(盲结构化方式)通信
2、Between Controller and Model
  • Controller对Model的访问完全不受限制,Model只能被获取
    Model中数据的改变,例如数据变化、数据库变化或者模型是某种网络数据库,一旦发生变化,Model通过notification/KVO发出类似广播一样的通知,只有使用到该Model的Controller才会接受该广播
3、Between Model and View
  • Model完全独立于View,互相之间一无所知
  • iOS开发中,开发人员最好不要让View具备接收Model广播的能力,因为这可能会违反MVC。

总结,在iOS开发中,我们以一个滚动视图scrollView为例,当View开始滚动,View先向Controller询问,“我是否可以滚”,被允许后,视图开始滚动,并向Controller索要数据,Controller转向Model获取数据,拿到数据后,通过dataSource把数据交给View显示。

Advantages and disadvantages


  • MVC仅仅是一种设计模式,MVC的好处在于分离了关注点,我们可以最大限度的重复利用代码,自动化UI测试也成为可能,大量的代码被移到单独的类文件管理。(所以不要再谈MVC能够为应用提高多少性能上的优化,也不要让我通过一个demo的功能演示来描述什么是MVC )
  • MVC的缺点是由于它没有明确的定义,所以完全理解MVC并不是很容易。使用MVC需要精心的计划,由于它的内部原理比较复杂,所以需要花费一些时间去思考。你将不得不花费相当可观的时间去考虑如何将MVC运用到你的应用程序,同时由于模型和视图要严格的分离,这样也给调试应用程序带来了一定的困难。每个构件在使用之前都需要经过彻底的测试。一旦你的构件经过了测试,你就可以毫无顾忌的重用它们了。
  • 根据开发者经验,由于开发者将一个应用程序分成了三个部件,所以使用MVC同时也意味着你将要管理比以前更多的文件,这一点是显而易见的。这样好像我们的工作量增加了,但是请记住这比起它所能带给我们的好处是不值一提。
  • MVC并不适合小型甚至中等规模的应用程序,花费大量时间将MVC应用到规模并不是很大的应用程序,通常会得不偿失。

我们对于 MVC 这种设计模式真的用得好吗?其实不是的,MVC 这种分层方式虽然清楚,但是如果使用不当,很可能让大量代码都集中在 Controller 之中,让 MVC 模式变成了 Massive View Controller 模式。

Ligher ViewControllers


常见的瘦身方法:

  • 将数据获取和转换的逻辑,抽取出一个类
  • 将拼接空间的逻辑,抽取出一个类

具体抽取哪些逻辑呢?

  • 将网络请求抽取到单独的类中:将网络请求与具体的第三方依赖库隔离,方便更换底层的网络库
  • 界面的拼装抽取到专门的类中:将能够复用的控件封装到一个类中,缺点是需要将控件的时间回调给Controller
  • 专门构造存储类:数据的存储放到专门的类中,方便使用的同时,可以针对存取做额外的事情,例如,对一些热点数据进行缓存等操作、数据迁移及切换存储底层等。
MYDay-第1期-Introduction to MVC-MVVM for iOS_第3张图片
累了!休息一下!

这里是休息区~~~比如,逗逗狗、撸一把...


MVC衍生的MVVM 架构


MVVM是Model-View-ViewModel的简称,MVVM模式依赖于数据绑定,能自动将对象属性和UI controls相联系是其框架级的特性。举个栗子,在微软的WPF框架里,ViewModel将TextField里的Text属性和Username属性绑定,如下所示:


WPF框架将两个属性绑定在一起。TwoWay绑定确保ViewModel中的Username属性改变时会为TextField的Text属性改变做准备,而且可逆.例如用户输入时ViewModel的变化。另一个例子是著名的基于MVVM的网页框架Knockout,你可以在动作里看到相似的绑定特性:


上面将HTML元素的一个属性和JavaScript模型绑定。
遗憾的是,iOS缺乏数据绑定的框架,但这正是ReactiveCocoa所扮演的角色:进行ViewModel连接"粘合"工作。从iOS开发的角度来看MVVM模式,ViewController和其相关的UI(无论是nib、storyboard或者纯代码组成的View)通过ReactiveCocoa将它们绑定在一起。

MYDay-第1期-Introduction to MVC-MVVM for iOS_第4张图片
MVVMReactiveCocoa.png

例如,我们创建一个ViewModel的新实例,继而构建和返回View。以下代码作用为初始化应用的navigation controller.

- (UIViewController *)createInitialViewController {
 self.viewModel = [RWTFlickrSearchViewModel new]; 
 return [[RWTFlickrSearchViewController alloc] initWithViewModel:self.viewModel];
}

总结,MVVM是一种设计架构,或者说是一种程序设计思想。MVVM中将ViewModel与View之间进行双向数据绑定。至于如何实现绑定,在iOS中采用的是ReactiveCocoa,使View拥有对ViewModel的引用,两者进行绑定。使两者得到同步。另外,ReactiveCocoa 经常在ViewModel里来监测它本身状态来进行其它操作。【结束:ReactiveCocoa单独成章介绍】

【学习链接】
MVVM与ReactiveCocoa的运用
MVVM Tutorial with ReactiveCocoa

你可能感兴趣的:(MYDay-第1期-Introduction to MVC-MVVM for iOS)