我怎么觉得ios开发者模式是什么意思中的MVC模式其实是MVP模式

在IOS中使用MVC感觉很奇怪对切换到MVVM存在疑虑?听过VIPER但是又不确定是否值得尝试?

继续阅读你会找到上面问题的答案,如果没有你想要的答案你可以去评论里骂我。

你將要开始学习一些有关ios架构模式的知识我们将会简单的回顾一些当前受欢迎的架构模式,并在原理上对他们进行比较然后做一些小例孓来实践。如果你需要了解更多详细信息我也为你整理了一些链接。

学习设计模式可能会上瘾所以要小心:读完这篇文章可能会给你帶来更多的问题,像这些

  • 谁应该做网络请求:模型还是控制器
  • 如何把一个模型传递到一个新的视图?

因为如果你不这样做总有一天你偠面对去调试几十个巨大的类的工作,你会发现自己暂时无法查找和修复任何bug你也很难再大脑里对这些类有一个总体的印象,所以你會一直无法修复或完善一些重要的细节。如果你的程序已经这样了那非常可能:

  • 你的UIViews几乎没事情做
  • 你的模型就是一个简单的数据结构

即便你遵循了苹果的指导,使用了也可能会发生这样的问题。不要灰心也有一些不妥当的地方,我们稍后来讨论这个问题

我们来定义┅下好的架构应该符合哪些特征:

  1. 角色实体之间的任务严格均衡分布;
  2. 可测试性(通常来自于上一条规则,在好的架构中很容易实现);
  3. 易于使用并且维护成本低;

当我们要弄清楚一件事如何工作的时候我们的大脑需要负载这件事情的复杂性。当然你越是成长你的大脑也越能适应并理解更复杂的事物。但这种能力并不是不断线性发展的很快你就会遇到一个瓶颈。因此要打败复杂性最简单的办法就是让每個实例负责单一任务()。

谁都不会怀疑单元测试为重构和添加新功能时遇到的问题带来的好处他也能让开发者模式是什么意思人员发现很哆运行时问题,如果这些问题等到在用户设备上被发现则修复并达到用户至少需要一个星期()。

这似乎不需要答案值得一提的是,最好嘚代码就是没有代码因此,更少的代码也代表更少的错误。写更少代码并不表示开发者模式是什么意思人员更懒惰你不应该总是倾姠于使用更完美的解决方案,而看不到他的维护成本

当涉及到架构模式时,我们有很多选择:

先假设一个应用分为三个部分:

实体的划汾使我们能够:

  • 更好的了解(因为我们已经知道模块是干什么的了)

让我们先从mv(x)模式开始然后在说VIPER。

在讨论苹果版本的MVC之前我们先看看传統的MVC()

在这种情况下,View是无状态的一旦Model发生改变,它就通过Controller来进行简单的呈现想想网页,一旦你按下某个链接浏览器就重新加载新的頁面。虽然在ios中是可以实现传统MVC的但是它的意义不是太大-三个实体是紧耦合的,每个实体都对其他实体可见这大大降低了模块的可偅用性-这就是为什么你的应用程序不使用MVC的原因。出于这个原因我们就不写MVC的例子了。

传统的MVC似乎不适合用于IOS开发者模式是什么意思

Controller是View和Model的中间人,让它们彼此不可见我们通常会构造一些最小可复用的Controller,但是一些比较棘手的不适合放在Model里的业务逻辑也会放在其中

從理论上来看,appleMVC看起来很简单但是你总感觉有些不对?你一定听到过有人构造了一个超大体积的Controller此外,View Controller的卸载成为了ios开发者模式是什麼意思者的一个重要问题为什么会出现这种情况那?为什么苹果要把传统的MVC改进成这样( )


CocoaMVC鼓励你写超大体积的View Controllers,因为它跟视图的生命周期非常相关很难说它们是相互独立的。尽管你可以分担一部分业务逻辑和数据转换工作到Model但是当涉及到释放工作的时候,你的选择并鈈多在大部分时间,视图的唯一责任就是发送动作到控制器视图控制器最终成了一个代理,并且负责数据以及收发网络请求相关的一切你能想到的任务

这种代码你见过多少次:

这个cell其实是一个视图,并且直接用模型进行配置那么这个违反了MVC准则,但是当你这样使用嘚时候并没有觉得有什么不对。如果严格遵守MVC则应该从视图控制器配置视图,而不是传递一个模型到视图但这样会让你的视图控制器变得更大。

在CocoaMVC中制造一个大体积的视图控制器是合理的。

这个问题可能并不明显直到它涉及到单元测试(如果你的项目中包含单元测試())。由于视图跟控制器紧密结合因此你想要测试视图的生命周期必须用一些非常有创意的办法,在以这种方法构造视图控制器时你的業务逻辑应该尽可能与视图布局分离。

让我们来看一个简单的例子:


但我们不能直接调用UIView的相关方法(viewDidLoad, didTapButton) 这可能会导致无法测试GreetingViewController视图的加载囷表示层逻辑(尽管上面的例子中没有太多这样的逻辑),这不是好的单元测试

事实上,在一个特定的模拟器上 (例如iPhone 4S)加载和测试UIView并不能保證它在其他设备上(例ipad)也能很好的运行。所以我建议从你的单元测试配置中删除“Host Application(宿主应用程序)”并在没有宿主应用的情况下进行测试。

視图和控制器之间的相互作用在单元测试中是不可测试的()

这样看来,Cocoa MVC似乎是一个很糟糕的设计模式但我们用文章开头的特点来评估它:

  • 分布 - 视图和模型分离,但视图跟控制器紧密耦合
  • 可测试 - 由于分配不好,你只能测试你的模型
  • 易用性 - 代码涉及的模式很少,并且每个囚都熟悉这种模式因此即便是没有经验的开发者模式是什么意思人员,也很容易维护它

如果你不准备在架构上投入更多时间,那么Cocoa MVC是伱的首选模式如果你觉得这种模式维护成本过高,那可能是你的项目设计过头了

从开发者模式是什么意思速度上来说,Cocoa MVC是最好的设计模式

是否看起来很像Apple’s MVC?的确是这样并且它的名字是MVP(Passive View的变体),这是否意味着Apple’s MVC其实就是MVP不,它不是如果你记得,在Apple’s MVC中视图和控制器是紧密耦合的,而在MVP中控制器是调解员、主持人,视图控制器的生命周期与视图无关并且可以很容易的模仿一个视图出来,因此Presenter可以没有任何布局代码它只负责更新数据和视图状态。


如果我告诉你视图控制器就是视图。

在MVP里UIViewController的子类其实都是视图,而不是Presenter這种区分提供了更好的可测试性,但却降低了开发者模式是什么意思速度因为你必须手动绑定事件和数据,你可以看看下面的例子:

关於装配的重要注意事项:

MVP模式恰好由三个独立的层组成我们不希望视图层了解模型,把模型呈现在视图控制器(在这里就是视图)里的装配昰不正确的因此,我们必须在别的地方做这个工作另外,我们可以使用应用级的路由服务来完成视图-to-视图的跳转这些问题不仅存在於MVP中,而是在所有模式中都需要注意

让我们来看看在MVP的特点:

  • 分布 - 我们划分了Presenter和模型,以及非常简单的视图(视图不对模型进行操作)
  • 可測试 - 优秀,我们可以测试大部分的业务逻辑由于视图只负责展示。
  • 易用性 - 在我们非常简单的例子中相比MVC,代码量几乎翻倍但MVP的思路佷清晰。

MVP在iOS中具有手段高超的可测试性和大量的代码

但是,正如我们已经说过的模糊的职责分离,视图和模型的紧密耦合是不好的笁作原理类似于Cocoa桌面开发者模式是什么意思。

于传统的VMC相比我没有看到这种架构的优势。

最新最大的一种MV(x)

是一种最新的MV(x)所以,我们希朢它的出现解决了之前MV(x)面临的问题

从理论上讲,Model-View-ViewModel看起来非常好其中的视图和模型都已经为我们所熟悉,其中的调解者被称为ViewModel。


  • 在MVVM中将视图控制器作为视图。
  • 还有就是视图和模型之间没有紧密耦合

那么,View Model在ios中怎么实现那它基本上与你的视图以及UIKit无关。View Model 在调用更新模型的同时更新自己而且由于我们有一个与View Model绑定的视图,所以视图也被相应的更新了

在MVP的部分我们简单提到过这个问题,这里我们讨論一下在OSX上系统已经提供了绑定工具,但是在IOS上却没有当然,我们有KVO和通知但他们不如绑定方便。

如果我们不希望自己实现这个功能那么我们至少有以下两种选择:

  • 一个基于KVO实现的数据绑定库 或者
  • 一个相关方面类库的列表 , 例如 , ,

实际上,现在如果你听到“MVVM”你可以認为就是ReactiveCocoa,反之亦然虽然你可以使用简单的绑定来实现MVVM,但大多数MVVM模式都直接使用了ReactiveCocoa(或其分支)

有一个关于响应式框架(ReactiveCocoa)惨痛的道理:权利越大责任越大。使用响应式框架很容易把事情搞砸换句话说,如果你在某个地方做错了你可能要花费大量的时间来调试程序,只要看看下面这个堆栈调用就能明白多麻烦了:

在我们的简单例子中使用FRF框架或者KVO都显得太重了。取而代之的是我们会明确的要求View Model使用showGreeting和简單的回调函数greetingDidChange更新视图

  • 分布-我们的小例子看起来不太明确,但是实际上MVVM的视图比MVP的视图责任更多第一所有状态更新需要用View Model建立绑定,第二所有事件只是由Presenter转发并不自己更新。
  • 可测试-View Model对视图一无所知这让我们很容易测试它。视图也可是可测试的但是它依赖于UIKit,伱可能希望跳过它
  • 易用性-在我们的例子中,其拥有的代码与MVP似乎一样多但是在真正的程序中,你应该不会手动绑定事件或更新视图如果你使用绑定,MVVM的代码量将会非常少

MVVM是非常有吸引力的,因为它结合了上述方法的好处此外,它不需要额外的代码更新视图因為视图的更新绑定在了视图里。同时可测试性也不错

乐高积木的经验转移到iOS应用中

是我们最后的备选,它比较特别因为它不是从MV(X)扩展絀来的。

现在你必须同意,细力度的责任划分是非常好的VIPER又一次迭代了责任划分,这里我们有五个层次。


  • Interactor - 包括数据实体、业务逻辑、网络请求等如创建新的实例,或者从服务器获取实例为达到这一目的而使用的一些服务或管理,不被视为VIPER的一部分而是作为一些外部依赖。
  • Entities - 你的数据对象而不是数据访问层,因为那是Interactor的责任

基本上,一个屏幕所展示的内容或者多个相关屏幕所组成的一个场景可鉯就是一个VIPER

你想用你的乐高积木做什么?随便你

如果我们用MV(X)来进行比较,就可以看到责任划分的不同之处:

  • VIPER有明确真对导航责任的模塊Router

使用合适的方式做路由是IOS应用的一个挑战,在MV(X)模式中根本没有解决这个问题

这个例子不包括模块之间的路由交互。因为以MV(X)作为主题并没有覆盖这个问题。


  • 分布 - 无疑VIPER是职能细分方面的冠军。
  • 可测试性 - 这里没什么惊喜更好的分布职责等于更好的可测试性。
  • 易用性 - 通过上面两个特点你可以猜到你必须写非常多的接口,以及很多非常小的类

当你开始使用VIPER时,你可能会有用乐高积木来建造帝国大厦嘚感觉着通畅是你的设计有问题的信号。也许这是你太早采用VIPER了(粒度太细),你应该考虑一些更简单的东西有些人忽略这一点,并继續用大炮打蚊子我想他们是认为当前阶段使用VIPER会在未来获益,即便当前维护成本有点高也可以接受如果你认同这个观点,那么我建议伱尝试?-生成VIPER框架的工具我个人觉得这就像是是用自动瞄准系统的火炮取代弹弓。

我们已经了解了这几种架构模式我希望你能够从Φ找到一些问题的答案。但是我相信你意识到了没有万能的架构所以选择架构模式是一个在特殊情况下权衡权重的问题。

因此在同一應用程序中混合不同的架构模式是很自然的事情。例如:你已经开始使用MVC然后你意识到一个特定的屏幕使用MVC太难实现和维护,切换到MVVM会變得简单的多但是为了这个特殊的屏幕,并不需要重构其它使用MVC能够很好工作的屏幕因为这两种架构很容易兼容。

让一切尽可能地简潔明了但又不能简单地被简化。 —?Albert Einstein

}

为什么要关注架构设计

因为假洳你不关心架构,那么总有一天需要在同一个庞大的类中调试若干复杂的事情,你会发现在这样的条件下根本不可能在这个类中快速嘚找到以及有效的修改任何blogs.com/bzhong/p/6064033.html

}

你对这个回答的评价是

下载百喥知道APP,抢鲜体验

使用百度知道APP立即抢鲜体验。你的手机镜头里或许有别人想知道的答案

}

我要回帖

更多关于 开发者模式是什么意思 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信