也谈MVVM

作者: 庸者的救赎 | 来源:发表于2016-11-27 21:56 被阅读533次

先说MVC吧

MVC,全称是 Model View Controller,是模型 (model)-视图 (view)-控制器 (controller) 的缩写。它表示的是一种常见的客户端软件开发框架;
MVC这个概念最早出现在上个世纪八十年代(目测本文的读者都还没有出生,当然笔者也没有出生)被提出,之后被广泛的应用于各类软件开发中.
iOS开发也不例外,iOS的系统架构就是典型的MVC,并且为我们实现了V层和C层的基础,然后开发者根据相应的数据补充M.这一切看起都很合理,而且开发者也一直都这么做着,并没有什么不妥
嗯,是的,没毛病...

但是事实真的如此么?
事实是,很多维护者会抱怨前人的代码多烂多烂,真的没法看,设计模式一塌糊涂等等;
这时候的MVC可能会变成(Massive View Controller),controller里面塞满了各类业务代码,多大上千行,甚至更多,如果注释写的好一些,勉强能看,如果没有注释...
为什么会这样?这里的原因太多了,比如有些开发者在做iOS之前并没有听说过MVC,有些即使知道MVC,也根本无法明确MVC到底干嘛的?面试官经常会问到这个问题,而得到的答案也仅仅是解释MVC概念之类,很少有人会在解释完概念之后再去仔细的阐述一下结构设计,代码规范之类...

下面我们仔细剖析一下,到底该如何MVC?

真正的MVC

我们来看看 MVC 这种架构的特点。其实设计模式很多时候是为了 Don't repeat yourself 原则来做的,该原则要求能够复用的代码要尽量复用,来保证重用。在 MVC 这种设计模式中,我们发现 ViewModel 都是符合这种原则的。

对于View来说,你如果抽象得好,那么一个App的动画效果可以很方便地移植到别的App上,而Github上也有很多UI控件,这些控件都是在View层做了很好的封装设计,使得它能够方便地开源给大家复用。

对于Model来说,它其实是用来存储业务的数据的,如果做得好,它也可以方便地复用。比如我当时在做有道云笔记 iPad 版的时候,我们就直接和iOS版复用了所有的Model层的代码。在创业做猿题库客户端时,iOSiPad 版的 Model 层代码再次被复用上了。当然,因为和业务本身的数据意义相关,Model 层的复用大多数是在一个产品内部,不太可能像 View 层那样开源给社区。

说完 ViewModel 了,那我们想想 ControllerController 有多少可以复用的?我们写完了一个 Controller 之后,可以很方便地复用它吗?结论是:非常难复用。在某些场景下,我们可能可以用addSubViewController 之类的方式复用 Controller,但它的复用场景还是非常非常少的。

如果我们能够意识到 Controller 里面的代码不便于复用,我们就能知道什么代码应该写在 Controller 里面了,那就是那些不能复用的代码。在我看来,Controller 里面就只应该存放这些不能复用的代码,这些代码包括:

  • 在初始化时,构造相应的 View 和 Model。
  • 监听 Model 层的事件,将 Model 层的数据传递到 View 层。
  • 监听 View 层的事件,并且将 View 层的事件转发到 Model 层。

MVC反面教材

直接上代码吧:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "tableviewcell", for: indexPath) as! TableViewCell
    cell.textLabel?.text = "二狗子"
    cell.imageView?.image = UIImage(named: "")
    return cell
}

上面这段代码,咋一看也没啥,因为只有6行而已,但是这是因为上面的cell数据加载很简单,只有一个textimage,但实际开发中,我们的数据可不是这样的,如果是新浪微博那种cell我想,单单是cell的数据加载都能写个上百行;所以这种写法是完全违反MVC原则的,因为你在C里面干了V的事情, C只应该做数据传递;所以,严格遵循MVC原则的写法是,不管cell的数据加载多么负责,代码都应该是下面这样的:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "tableviewcell", for: indexPath) as! TableViewCell
    cell.userModel = dataModel[indexPath.row]
    return cell
}

如果你的tableview是个标准的反面教材,请在评论区留下你的大名📌

这里只是简单的做了一些代码结构的调整,但是确实符合了MVC原则,但是在controller中往往不止这些东西,controller最头疼的问题,就是网络请求问题,因为复杂的界面会涉及到很多数据请求,而这些请求也会伴随着界面和数据的变化,这些逻辑写上去,那么controller的代码量瞬间就上去了,几个版本迭代过去,你懂的!所以,达到上千行只是时间问题?

何解?
在网上关于这个问题的答案有很多,比如分离网络业务层,直接放到一个专门的业务模块里面,MVVM就是在这种情况下衍生出来的.

MVVM

MVVM的历史,这里就不赘述了,感兴趣的同学直接百度,一大把,先看看一张基本上只要谈到MVVM都会放的一张图:

MVVM结构图

上面这张图,我想很多人肯定不止一次看到过

这个图准确的描述了什么是MVVM:一个MVC的增强版,让viewviewcontroller直接结合在一起,使用ViewModel进行链接,并将逻辑从controller里面移出放到ViewModel;MVVM听起来很复杂,但是他本质还是MVC,只不过在结构上做了调整;这样viewmodel彻底解耦了,那么这个时候他们之间的通信会变得有些奇怪了,因为他们中间跨越了一个层,所以在MVVM的使用当中,通常会利用双向绑定技术,使得Model的变化能同步更新到View
那么这里就得提到一个框架:ReactiveCocoa(swiftObjective - C都支持,但是在Swift上更推荐使用RxSwift);

ReactiveCocoa是一个基于Cocoa封装的函数响应式框架,使用它可以轻松的实现数据的绑定;所以,每每谈到MVVM的时候,总会提到它;但ReactiveCocoa可以不想其他三方框架那般,看看Document就可以开心的撸起来了,ReactiveCocoaDocument都能写成一本厚厚的书了,而且最关键的是,它的编程思想,函数式,响应式,数据流...
还有它那魔性的语法.

当然了ReactiveCocoa也提供了很多便捷:

  • 函数式,提供了很多函数式操作(对于Objective - C来说,Swift本身自带)
  • 数据绑定,很多时候可以代替KVO,delegate
  • 动态声明

更多信息可以去官网阅读相关文档,本文这里不做太多探讨;

要换MVVM?

既然MVVM有那么多好处,为何不换?
在移动开发领域,MVVM提出也不短了,可大部分项目还是使用MVC,只有少部分项目会用;还有一部分项目会有专门的架构师,为项目设计架构,他们会搞出一些大家都不懂的东西,然后在某个分享会上分享给大家;
但是!
我们要想清楚,你的项目真的需要MVVM么?
不一定吧?
如果你的项目本来就不复杂,为何要换?MVC就挺好的,别听那些"分享"
笔者不是说那些分享不好,好,确实好,但,那是在他们的项目上用呀,他们都是就职于BAT这样的大厂的

一笑而过?

通过上面的阅读,相信你已经对MVCMVVM有所了解,那么问题来了.

该用什么?

相信,很多iOS开发者在找工作面试的时候都被问过MVVM,基本上都快成了必问点了

我们不好说,哪个更好,哪个更适合.根据自己的情况选择
MVVM的学习路线相对要难很多,但是空闲的时候尝试一下也是个不错的实践,其中收获必定不小的
至少下次吹牛或面试的时候,你也多一些谈资不是?

生命不息,折腾不止...
I'm not a real coder, but i love it so much!

相关文章

  • 也谈MVVM

    先说MVC吧 MVC,全称是 Model View Controller,是模型 (model)-视图 (view...

  • iOS设计模式文章列表

    iOS应用架构谈 开篇 MVVM核心概念 长篇高能 ReactiveCocoa 和 MVVM 入门

  • Jetpack之Lifecycle、LiveData及ViewM

    在《也谈Android应用架构》中我们对MVC、MVP、MVVM进行了详尽的分析,但还有一个问题悬而未决,那就是生...

  • 前端Vue框架面试题大全

    谈一下你对 MVVM 的认识 https://blog.csdn.net/Dora_5537/article/de...

  • Vue知识点

    1、对于MVVM的理解 MVVM 是 Model-View-ViewModel 的缩写。Model代表数据模型,也...

  • 也谈谈MVVM(一)

    本文转自 从学习iOS开发就开始接触到MVC的开发模式了。随着越来越注重用户体验以及业务越来越复杂。ViewCon...

  • Vue学习(基础)

    MVVM模型 MVVM是Model-View-ViewModel的缩写。 Model:代表数据模型,也可以在Mod...

  • 前端MVVM模式从理论到实战 (一)

    最近在研究mvvm开发模式,仿照着vue写了一套简单的mvvm代码,也顺便来记录一下 在说mvvm模式之前先简单解...

  • vue

    一:什么是MVVM? MVVM是Model-View-ViewModel的缩写Model 层代表数据模型,也可以在...

  • 值得学习的技术文章(持续添加)

    1. MVVM 学习资料 MVVM奇葩说 面向协议的 MVVM 架构介绍 MVVM With ReactiveCo...

网友评论

    本文标题:也谈MVVM

    本文链接:https://www.haomeiwen.com/subject/cbvnpttx.html