三种框架的比较—教你认清MVC,MVP和MVVM

什么是MVC

MVC,Model View Controller,是软件架构中最常见的一种框架,实际就是把业务逻辑、数据、界面显示的代码分开组织,各层专注于各自的功能,易于扩展、管理等

在具体开发过程中,MVC就是通过controller的控制去操作model层的数据,并且返回给view层展示,如图

最正确的关系

MVC三层之间的关系

Apple是这样说的,在MVC下,所有的对象被归类为一个model,一个view,或一个controller。Model持有数据,View显示与用户交互的界面,而controller调解model和view之间的交互。

  • View层
    继承自系统视图基类封装的所有自定义View
  • Model层
    针对业务模型,建立的数据结构和相关的类,它主要负责网络请求,数据库处理,I/O的操作。
  • Controller层
    安卓的activity,iOS的UIViewController层,用来初始化界面,网络请求展示数据,还要处理view层的交互事件,具体的业务逻辑等

MVC存在什么问题

MVC经典的被用了那么多年,有问题吗?当越来越复杂的业务逻辑需要处理,无数个model view controller,我们需要三者之间进行通信,回调,事件传递,我们发现MVC是有问题的,或者说实现绝对的MVC很难


view和Controller

view和model
  • 1、经典存在问题是大部分写MVC的结构都是这样的,model管理数据,Controller中引用model当作属性,Controller中引用view当作属性,view中Import model当作预留属性(这句便是耦合,将M和V建立起了关系),使用时是这样的,Controller来调度View和Model(承载view将Model数据进行展示,Controller中的网络请求来更新Model,同时通过View的Setter方法更新view),这样可以说是V被M给耦合了。这便是经典MVC存在的弊端,但是为什么还有好多人去这么写?是因为快!操作快,这就是伪MVC的经典好处也是存在的耦合弊端。

  • 2、controller的负担随着业务的复杂度持续增高,数据请求,初始化视图,处理业务逻辑,臃肿的controller导致代码不易维护,也增加了测试的复杂度

什么是MVP

MVP作为MVC的演化,解决了MVC不少的缺点,MVP的model层和MVC是一样的,而view和controller都属于view层,所有关于用户事件的转发全部交由presenter层处理。下面还是让我们看图

MVP
  • 1、View就是MVC的view和controller,在MVP中只负责view层,如controller只负责初始化视图,view展示
  • 2、presenter层替代了原来controller层的网络请求,业务逻辑等所有关于用户事件的转发处理
  • 3、Controller会持有Presenter,同时持有View,通过presenter获取到model层数据,那View层怎么和presenter通信呢,需要View层定义API,比如刷新资讯推荐列表,刷新banner数据,Persenter在获取到model之后,调用View层的API进行数据展示
  • 4、如此一来,Preseter实现了Model和View的完全解耦。代码可复用性高了,维护成本低了,实现了测试驱动开发(调用presenter的方法就能测试,不依赖视图)
  • 5、问题:1. 随着业务逻辑的增加,一个页面可能会非常复杂,UI的改变是非常多,会有非常多的case,这样就会造成View的接口会很庞大。
MVP使用案例,伪代码
  • View 层
//新闻listView,1 进入时的数据加载动画,2 数据加载完成后展示,隐藏加载动画,3 数据加载失败(网络原因等)要给用户反馈
Class NewsView(){
   func showLoadingView();
   func showNewsList(newsList[]);
   func hideLoadingView();
   func refreshLikeStatus(isLike);
   func refreshCollectStatus(isCollect);
   ......
}
  • Model 层
// 新闻Model,1 定义新闻字段,2 缓存新闻数据,3 读取新闻缓存数据
Class NewsModel(){
   String  newsID;
   String  newsTitle;
   String  newsIcon;
   String  newsUrl;
   String  newsTime;
   func  cacheNewsList(newsList[newsModel]); // 缓存
   func  readCacheNews( ) -> Array;  //读取缓存
}
  • Presenter 层
//Presenter,1 请求新闻数据,  2 调用NewsModel缓存新闻数据,  3 调用View层接口刷新UI   4 处理用户事件
Class Presenter(){
   private  newsV: NewsView;  
   private  newsM: NewsModel;
   func requestNewsData(url,param);
   func likeNews(newsModel); //点赞
   func shareNews(newsModel);  //分享
   func collectNews(newsModel);  //收藏
}
  • Controller 层
//新闻列表控制器,1 初始化视图进行展示   2 初始化presenter进行网络请求  
Class NewsController(){
   private newsView: NewsView;
   private newsPresenter:Presenter
   func  createView();
   func  layoutView();
}
MVP

MVVM和数据绑定(DataBinding 和 RAC)

MVVM+数据绑定解决了MVP中View层可能会API过多的问题

实际项目中需要事件传递,不同对象间通信,也就是一方的变化需要传达给另一方,传统的实现方式有通知、代理、观察者模式等等,但是这些方法代码分散,不易维护和管理,所以数量不宜过多;数据绑定机制(单向绑定和双向绑定)就解决了这一问题,iOS中有RAC,安卓有DataBinding,前端有VUE

在MVVM中,由于ViewController持有ViewModel,而ViewModel不能反向持有ViewController,所以,当ViewModel中发生变化时,需要通知ViewController,所以需要将ViewModel中的一些内容与ViewController绑定起来,这称为单向绑定;有时ViewController和viewModel中任何一端发生变化,对方都能知道,这称为双向绑定。ViewModel与Model之间的关系同理。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容