我们开发软件中应用各种模式,主要是为了

  1. 职责划分:一个类只做一件事
  2. 易用,可维护,方便扩展
  3. 解耦,相互独立,可单独测试

各种设计模式其实都是在解决上面的问题,让我们对比看看吧。

一、如何理解MVC设计模式

在通常的定义中,MVC 是下图的结构

但是在 cocoa 体系中,苹果建议的 MVC 模式如下图所示

在斯坦福课程中,解释的 MVC 如下图所示

综合一下在 cocoa 系统中可以这么理解:

  • M model,存储、定义、操纵数据
  • V view,用户看到的UI,能够和用户交互
  • C controller,协调者,把 model 的数据放到 view 中展示,相应 view 的交互改变 model
    特别在 cocoa 系统中
    C 持有一个 model,直接操作 model;model 通过 KVO、通知等方式抛出自己改变的事件
    C 通过 IBOutlet 或者直接持有一个 view,他可以直接操作这个view;view 有了交互,可以通过action target 方式 以及 delegate 方式 让 controller 来响应事件,但是 view 并不知道具体是哪个类对象;view 的需要的数据,可以通过 protocol 的方式,让 controller 实现这个 protocol 并且成为 view 的数据源,来提供数据给 view,view并不需要知道 controller 的具体的类对象。

最简单的例子就是 UITableviewController,他一般会持有一个 NSArray 作为 model,同时根视图就是一个 UITableView,这是 view。controller 从网络或者本地加载数据赋值给 array,然后 reload tableview。tableview 绘制时请求数据源,相应用户事件会通过delegate 发起调用。tableview 与 array 并没有直接的关系。

进一步的,如果我的页面很复杂,那么这个 MVC 是怎么处理的呢?看看斯坦福的另一张讲义:

也就是 cocoa 中,Controlelr 控制的 view 可以是属于别的 MVC 中的,最外层的 MVC 来管理这些子 MVC。所以最好不要一个 C 中对应多个 view 或者 model,而是需要拆分成多个 MVC 来。

缺点:

  1. 如果严格按照MVC模式的话,不像 view 传递 model,那么代码就会臃肿,想象往一个cell 设置用户信息,单独传一个 userModel,然后 cell 内部处理会很简洁,如果分开在controller 里面传 头像、姓名、签名,就会很臃肿
  2. view 和 controller 一般都是绑定在一起的,生命周期的控制依赖于 controller,独立测试会很不方便

二、MVP 模式

基于 MVC 的缺点和优点,既然 view 和 cocoa 中的 viewController 已经那么强的紧密耦合了,那么把这两者看成同一个东西,一起做为一个 view 。
Model 层负责数据的增删改查(网络,数据库查询,本地文件读写)。
Presenter 层只是一个中介,负责数据的转发。

上图展示的是 View 持有 Presenter,Presenter 持有 Model。所以 Presenter 不依赖于具体的 View,这个可以通过 Protocol 来实现,让 View 实现一些数据更新的协议,presenter 就可以不知道View 具体是什么就能传递数据。

优点:
每一层的任务互相独立分开了,让测试更加方便。

** 缺点:**
代码量会提升很多。

示例见参考2.参考2的复杂MVP可以简化如下图所示:

三、MVVM 模式

MVP 的 Presenter 需要主动更新 view,如果增加一个绑定机制呢,model 的改变及时反馈在 view上会不会更酷。但是这样就会让 model 和 view 关联起来,所以就出来一个 viewModel 的东西。

ViewModel 持有 Model,管理 Model 并可以把 Model 中的数据处理成 View 需要的数据。同时可以处理用户输入验证逻辑,视图显示逻辑,发起网络请求和其他各种各样的代码。
View 持有 ViewModel,并且和 ViewModel 中的数据绑定,让 ViewModel 中的数据改变及时反应在 View上;并且把一些按钮事件的 target 设置给 ViewModel。

优点:

  • View Model 的引入配合状态流和响应式编程使得 App 的结构更加清晰,交互更加流畅。
  • MVVM 中的 View 责任多一点,因为要设置绑定,但也因为绑定,所以代码量更少。测试时主要是测试 View Model 和 Model 。

缺点:
因为数据的双向绑定,让BUG的定位更加困难,过大的项目也会耗费更多的内存。

四、VIPER 模式

VIPER 其实是 MVP 的一种扩展,VP不变,M变成了 Interactor 和 Entity,外加一个 Routing。Entity 就是 model 的数据结构, Interactor 就是处理 model 的类,增删改查model,Routing 就是控制视图的跳转。可以看到 viper 模式分的更细,每层的功能更明确,更容易测试。但是也更复杂,代码量也会更加庞大。

可以参考下面两个图结构图。
图一:

图二:

参考1.https://www.objc.io/issues/13-architecture/mvvm/
参考2.https://github.com/amacou/MVPExample
参考3.https://www.objc.io/issues/13-architecture/viper/

iOS 中架构模式的浅显理解的更多相关文章

  1. IOS中KVO模式的解析与应用

    IOS中KVO模式的解析与应用 最近老翁在项目中多处用到了KVO,深感这种模式的好处.现总结如下: 一.概述 KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修 ...

  2. iOS - MVP 架构模式

    1.MVP 从字面意思来理解,MVP 即 Modal View Presenter(模型 视图 协调器),MVP 实现了 Cocoa 的 MVC 的愿景.MVP 的协调器 Presenter 并没有对 ...

  3. iOS - MVVM 架构模式

    1.MVVM 从字面意思来理解,MVVM 即 Modal View ViewModel(模型 视图 视图模型).MVC 是一个用来组织代码的权威范式,也是构建 iOS App 的标准模式.Apple ...

  4. iOS - MVC 架构模式

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

  5. iOS软件架构——架构模式(Architectural Pattern)

    一个架构模式描述软件系统里的基本的结构组织或纲要.架构模式提供一些事先定义好的子系统,指定它们的责任,并给出把它们组织在一起的法则和指南.有些作者把这种架构模式叫做系统模式[STELTING02]. ...

  6. iOS - VIPER 架构模式

    1.VIPER 从字面意思来理解,VIPER 即 View Interactor Presenter Entity Router(展示器(视图) 交互器 协调器 实体(数据) 路由器),迄今为止,划分 ...

  7. 初学者对于MVC架构模式学习与理解

    理解MVC的工作原理,明白一个网页是如何显示出来的 之前一直盲目的在慕课上看视频,脑袋里想着要理解mvc,看了mvc相关的视频,看完之后就觉得空白白的,M,V,C各代表什么我知道,但是这个究竟有啥意思 ...

  8. 【原】IOS中KVO模式的解析与应用

    最近老翁在项目中多处用到了KVO,深感这种模式的好处.现总结如下: 一.概述 KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知.简单 ...

  9. iOS 中self和super如何理解?

    或许你理解self和super都是指的是类的对象   self指的是本类的对象,而super指的是父类的对象,但是事实情况呢,可能有些和你想象的不一样? 简单看下下面例子: @interface Pe ...

随机推荐

  1. Discuz!在线中文分词服务

    Discuz!在线中文分词服务是基于API返回分词结果的.在项目中,我们只需要一个函数即可方便地进行分词.关键词提取.以下是根据Discuz!在线分词服务API写的函数,测试可正常运行: 代码代码如下 ...

  2. WPF实战俄罗斯方块

    概述 本文试图通过经典的游戏-俄罗斯方块,来演示WPF强大的图形界面编程功能. 涉及的图形方面有这几个方面: 1.不规则界面的设置 2.布局系统的使用 3.2D图形的应用 4.输入事件的响应 5.风格 ...

  3. C语言的谜题

    本篇文章<C语言的谜题>展示了14个C语言的迷题以及答案,代码应该是足够清楚的,而且我也相信有相当的一些例子可能是我们日常工作可能会见得到的.通过这些迷题,希望你能更了解C语言.如果你不看 ...

  4. ThinkPHP微信扫码支付接口

    最近折腾微信扫码支付,看了微信官方文档,找了很多网页,发现和文档/demo不匹配,现在自己算是弄出来了(文件名称有所更改),贴出来分享一下 一.将有用的官方lib文件和使用的相关文件放置到vendor ...

  5. Python中模块

    模块 模块对我来说是什么 模块对我来说,感觉就像亲属或者朋友已经走过的路,他们已经趟过的浑水.掉过的坑.践行过的路线,全部提供给你,在你需要的时候请求帮助,借鉴他们的解决方法一样.都是为了方便走好人生 ...

  6. python 实现查找某个字符在字符串中出现次数,并以字典形式输出

    把字符串'aenabsascd'中的字符出现的次数统计出来,并以字典形式输出 方法一: def count_str(str): dic={} for i in str: dic[i]=str.coun ...

  7. jquery实现漂亮的轮播图

    今天工作中要用到一个轮播功能,在网上找了一些,觉得有些过于繁琐,于是自己动手写了一个,效果如图: 代码如下: <!DOCTYPE html> <html lang="en& ...

  8. linux重要目录

    1.网卡配置文件 /etc/sysconfig/network-scripts/ifcfg-eth* 2.客户端dns配置文件 /etc/resolv.conf 网卡配置文件中的dns配置优先于此文件 ...

  9. 开发Web版一对一远程直播教室只需30分钟 - 使用face2face网络教室

    转载自:https://blog.csdn.net/wo_shi_ma_nong/article/details/88110111 在“为网站开发远程直播教室的折腾过程及最终实现”中,介绍了如何使用f ...

  10. C++中一个0xC0000005访问冲突问题

    在冯.诺依曼结构CPU(如i386,ARM A8,A9)的保护模式或者哈佛结构(如8051, ARM M0,.. M3)的CPU下,C++编译器将放置常量的内存设置为只读模式或者放入只读内存中,如果出 ...