什么应该拥有 MVC 模式中的模型?

Posted

技术标签:

【中文标题】什么应该拥有 MVC 模式中的模型?【英文标题】:What should own the model in an MVC pattern? 【发布时间】:2013-03-05 09:53:27 【问题描述】:

从我记事起,我就一直在制作 ios 应用程序,但直到最近我获得了一份实习编程经验,我的编程风格还没有成熟多少。我很早就学习了许多 OO 概念,因为我意识到如果不了解它们,生活就会很糟糕,但我从未让自己学习过的一件事是 MVC 模式。

为了给出上下文,假设我在单个SolarSystemViewUIView 的子类)内绘制了一个太阳系。我的SolarSystemView 应该有一个SolarSystem 类的实例变量(一个包含具有所有重要行星和恒星属性的数据结构的类),还是应该归SolarSystemViewController 的实例所有?还是完全不同的东西?我找不到任何给出满意答案的示例代码。

我想如果视图拥有模型,操作会非常流畅,但这也不像是好的风格。毕竟,SolarSystem 实例必须以某种方式动态更改,并且以与SolarSystemView 更新相同或相似的速率。

【问题讨论】:

【参考方案1】:

在 MVC 范式中,模型应该与视图分离。为了获得它需要自己绘制的数据,它会向 Controller 请求它,而 Controller 又会向 Model 请求它。这样,我们将信息与 GUI 分离。如果有帮助,可以将其视为模型控制器视图。因此,在大多数情况下,控制器“拥有”模型。

例如,在 cs193p 中,CalculatorViewController(控制器)有一个 CalculatorBrain(模型)属性,它与之交互以获取方程式的结果以显示在视图中。

在您的特定示例中,SolarSystemViewController 可能会强烈引用SolarSystem,它将轮询将移交给SolarSystemView 的数据,以便它可以在需要更新时自行绘制. SolarSystemView 还可以在用户与其交互时通知SolarSystemViewController,以便它可以显示其他视图或更新SolarSystem,以及它可以执行的任何其他任务。

请注意,Cocoa 和 Cocoa Touch 中的 MVC 范例与其他更通用的 MVC 版本(如 Smalltalk)略有不同。例如,如果您查看Wikipedia page on MVC 图表,那里的图表应该与您所学的有所不同。事实上,GoF(Design Patterns)就是这样描述 MVC 的。

MVC 由三种对象组成。模型是应用程序 对象,视图是它的屏幕呈现,控制器 定义用户界面对用户输入的反应方式。在 MVC 之前, 用户界面设计倾向于将这些对象集中在一起。 MVC 将它们解耦以增加灵活性和重用性。 MVC 解耦视图 和模型通过在它们之间建立订阅/通知协议。一种 视图必须确保其外观反映模型的状态。 每当模型的数据发生变化时,模型都会通知视图 依赖它。作为回应,每个视图都有机会更新 本身。这种方法允许您将多个视图附加到模型以 提供不同的演示。您还可以为 无需重写的模型。

在这两种情况下,模型本身都在联系视图以更新它。然而,在 iOS 上,Model 和 View 之间的交互是通过 Controller 来处理的。这在first session of cs193p 和Apple's own documentation on MVC relationships. 中有很好的解释。这样,您只需要重写控制器代码即可在其他地方重用模型和视图。

这是来自 cs193p 的 MVC 图来澄清。

【讨论】:

这完全涵盖了我的要求;我有一个额外的询问。 “打勾”应该怎么做?显然,行星需要有一个刻度才能继续移动。如果我理解正确,它将是拥有计时器的控制器,此时它会调用模型更改,然后从模型中检索数据并将其显示在屏幕上,对吗?这可能是一个单独问题的内容。 @CarterPape 是的,这听起来对我来说是正确的。 Controller 通常会处理 Model 的更新,然后通知依赖它的 View 进行更新。例如,游戏的运行循环将存在于 Controller 中,并且在通知 View(例如 GLKView)更新之前,它会通知游戏中的代理(模型)进行自我更新。【参考方案2】:

在这种情况下,SolarSystemView 不应包含 SolarSystem 类的任何瞬间。 SolarSystemViewController 应该是您的视图 (SolarSystemView) 和模型 (SolarSystem) 之间的过渡。

【讨论】:

以上是关于什么应该拥有 MVC 模式中的模型?的主要内容,如果未能解决你的问题,请参考以下文章

我应该在 DAL 中使用哪种设计模式,同时拥有具有不同模型的多个数据库源?

为啥UIImageView拥有UIImage。它是不是违反 MVC 原则?

MVC 设计 - 我可以/应该/必须在 CodeIgniter MVC Web 应用程序项目中拥有多少个控制器?

OPENCV学习笔记3-4_使用模型-视图-控制器设计应用程序

CoreData 设计模式:我应该拥有多个或多少个 NSPessistentObjectContexts 的单个对象?

Spring MVC系列Java中的单例模式