我喜欢MVVM MVVM

我在代码方面的许多著作都涉及构建应用程序的较小方面。 诸如酷框架,惯用Swifty之类的事物。 更不用说构建项目的整体方式了。 今天,情况发生了变化。

应用程序的总体结构有几种常见的设计模式。 Model-View-Controller是最简单的并且可能是最常见的。 您有一个表示用户界面的视图,一个控制UI逻辑的控制器和一个表示对象或某些数据的模型。 视图与与模型对话的控制器对话。 模型和视图从不直接通信。 这很棒,但是缺点是很多逻辑都是由控制器处理的。 通常,这会导致我们的View Controller中产生大量代码,并可能导致您对程序的哪一部分负责逻辑的哪一部分感到困惑。 这就是MVVM的来源。

MVVM代表Model-View-ViewModel。 它在模型和视图控制器之间增加了抽象的额外步骤。 在这种模式下,您的视图与MVC中的视图控制器一样,与视图控制器对话,从而使VC知道任何用户交互。 然后,视图控制器与视图模型对话,而后者又与模型对话。 在这种情况下,所有业务逻辑都将从视图控制器中删除并放置在视图模型中。 控制器现在只有两个工作:使用视图模型提供给它的数据,在视图内发生用户交互时通知视图模型,并通知何时更新视图。

这些就是基础。 接下来是找出一种方法来使每个步骤(模型,视图模型和视图/视图控制器)相互对话。 一种常见的方法是使用功能性反应式编程框架。 FRP超出了本周的发布范围,因此我不再赘述。 这是考虑编码的一种很酷的方法,因此,如果您有兴趣,请务必查看ReactiveSwift和RxSwift。 我还遇到了ReactiveKit,它似乎更轻量级,并且如果您以前没有看过反应式编程,可能会更容易进入。 我一直在寻找进入反应式框架的借口,也许我刚刚找到了它。

使您的视图/视图模型/模型组件相互交谈的另一种方法是通过键值观察。 我上周谈到了KVO。 我们将模型建立为具有可观察的属性,并将这些属性的观察者添加到我们的视图模型中。 然后,视图模型对属性执行任何必要的逻辑,然后它们自身将更新一些观察到的属性,视图控制器正在观察这些属性。 该方法具有一定的优缺点。 从好的方面来说,您可以在MVVM体系结构的每一层之间保持高度的独立性。 您的类/结构将非常独立并且易于测试。 缺点是Swift中的KVO继承了Objective-C的许多丑陋之处。 尽管它在Swift 3中确实做了很大的改进,并且在Swift 4中还有更多的改进,但是与Swift中的大多数操作相比,该语法显得笨拙。 就个人而言,我认为优点远胜于缺点,但您会经常听到开发人员抱怨在Swift中使用KVO。

第三种选择(尽管我没有看到太多的开发人员在MVVM中使用),是使用委托模式来实现MVVM。 如果您不熟悉使用协议的委托模式,这里有一个很好的总结。 您的视图模型将具有用于信息的模型的实例。 视图模型将自己声明为该模型的委托。 每当模型更新时,它都会触发在“ ModelDelegate”协议中声明并在视图模型中实现的函数。 视图模型和视图控制器之间发生相同的关系。 代表团也有一些优点和缺点。 一个很大的缺点是您非常有意地将模型耦合到视图模型,并将视图模型耦合到视图控制器。 这消除了体系结构每个级别的某些独立性。 您不得不仔细考虑何时更新视图。 逻辑上的分离变得不太清晰,这首先使使用MVVM的目的略有逊色。 使用委托的好处在于,面向协议的编程是Swift所要做的事情之一。 语法很简单,很难理解您的意图。

因此,既然我们掌握了MVVM的基础知识,那么我已经建立了一个项目供您浏览,如果您想了解它是如何工作的。 如果在实际项目中看到它,可能更容易阅读,所以这里是github存储库的链接。 我所做的只是以上周的KVO为例,并使用MVVM架构对其进行了重构。 模型和视图模型通过KVO进行通信,而视图模型和视图控制器通过委托模式进行通信。

这就是MVVM! 我认为这是构建项目的好方法。 与往常一样,在下面留下任何问题或评论,希望您度过愉快的一周!