视图和模型是否应该沟通?


33

根据MVC体系结构Wikipedia页面,视图可以由模型自由通知,也可以自由查询模型的当前状态。但是,根据Paul Hegarty在Stanford的第1讲第18页上的iOS 5课程的介绍,所有交互都必须通过控制器进行,而Model和View则永远都不应该相互了解。对于我来说,尚不清楚Hegarty的声明是否一定要简化课程,但我很想说他打算这样做。

您如何解释这两种相反的观点?

Answers:


26

这是MVC / MVVM中一个有争议的主题。有人说可以让View直接访问模型,也有人说您应该将模型包装在ViewModels中,以便将它们从View中抽象出来。我个人不喜欢这两种方法。

MVC / MVVM的主要目标之一是分离UI,业务逻辑和数据。因此,考虑到这一概念,允许视图直接访问模型会创建您可能不想拥有的依赖项。另一方面,将模型包装在ViewModels中通常很乏味,并且用处不大,因为ViewModels往往只是充当模型的传递对象。

我喜欢让模型实现特定接口的方法,我们称其为IModel。然后,您的ViewModel类可以提供实现IModel以供View使用的对象的实例。视图只是知道它可以与从ViewModel获取的IModel对象一起使用。这样就删除了多余的ViewModel包装器代码,并从View中隐藏了IModel的具体实现。您以后可以将IModel的一种实现换成另一种,而不会影响View。


1
关于将模型映射到视图模型的繁琐方面,应该注意的是,有一些可用的工具可以减轻映射的痛苦。EG:(.NET AutoMapper)(JAVA modelmapper)
Jesse

+1好答案!根据模型的复杂性,这是一种很好的方法,但是当今大多数模型都是Anemic类型的。该模型的元素只不过是没有行为的数据对象,因此我几乎不需要这种抽象,也几乎没有允许View直接访问模型的危险。
maple_shaft

2
我听到你在说什么;大多数IModel接口仅包含一堆属性声明和少量(如果有的话)方法声明。但是,即使模型是贫乏的,该界面仍会将View与它们的具体实现分离。分离不是每个项目都必须的,但始终保持选择打开始终是一个好主意。
雷蒙德·萨尔特雷利

1
我很困惑,如果您有一堆绝对不同的视图,那么如何才能依靠一个界面而不弄乱它呢?我认为视图模型很棒。您创建的模型足够通用,可以在整个应用程序中使用,并且您可以创建视图模型以使用一个或多个模型,并另外实现只能由该视图使用的操作。
松饼人

12

在网络上,每个人都将他们的去耦MVC称为。

某些技术(例如C#)使用MVVM,因为View与其他视图之间没有链接,所有内容都通过服务定位器来绑定变量。

在纯MVC上,视图直接与模型对话,反之亦然。仅当发生任何更改时,控制器才在那里。

然后,有一个称为PAC(表示抽象控制)的控制器。在这种体系结构中,视图和模型不会互相交谈。控制器是唯一允许对视图或模型执行任何操作的控制器。人们经常将其与MVC混淆。

您会在这里看到更好的解释方式:http : //www.garfieldtech.com/blog/mvc-vs-pac


7

对我来说,架构的基本目标是不妨碍将来进行重构的尝试。通常,与模型直接交互的视图会满足此要求,并且在不满足要求时就相对清楚。

当视图变得与模型过于亲密时,ViewModel可能是一件很漂亮的事情,但对我而言,通常情况是,调用它的实例很少。


6

MVC中,Paul Hegarty是错误的。控制器是关于用户事件的,而不是模型到视图的通信。在经典MVC中,视图观察模型(观察者模式)。

在中间人之间进行调解时,该模式应称为MVP,实际上,当今呈现为MVC的大多数实际上更接近MVP。

然后是MVVM,两者彼此相似,但又有所不同,并且存在很久了……最好将其视为通过viewmodel对象绑定在一起的两个MVC / MVP-“客户端” MVC的viewmodel为它的模型,而“服务器” MVC将viewmodel作为其视图。


1
今天(2014年初),对我来说(带有我的节点和角度堆栈),在“客户端” MVC和“服务器” MVC上的区别似乎非常相关,并且在某种程度上具有启发性。(谢谢)
slacktracer 2014年

4

由于您特别是在询问斯坦福大学的讲课内容,因此,有必要考虑一下有关Hegarty立场的两件事:

  1. 正如您所提到的,他正在教授100级的计算机科学课程。在他的演讲中,他有很多地方可以简化,掩饰细节或说“只是这样做”,就像在教授基础知识时可能要做的那样,即必须先掌握规则,然后才能打破规则。
  2. 我在iOS SDK上的经验是,在不强制 View和Model之间严格分离的情况下,它非常倾向于该模式。特别是在编写iOS应用程序时,坚持模型视图分离可以帮助您编写符合框架期望的代码。我会毫不犹豫地将Hegarty的声明推广到其他平台或一般平台上的开发中。

1

我确实同意保罗·哈加蒂(Paul Hegarty)的观点,并认为该观点一定不能了解该模型。实现起来并不难,但是它为您的设计和未来的灵活性带来了更多好处。

在小型应用程序(通常是台式机)中,我希望避免使用“虚拟” ViewModel类并简化操作,因此我也使用IModel接口(请参见上面的答案),并请注意Model不了解View(使用订阅服务器)就像在传统的MVC中一样)。

同样,在这种情况下,控制器已与视图紧密结合,为简单起见,我并不总是将它们分开。

当您可能对同一模型有多个视图时,第二种“简化”方法是可以的,但是如果您想对不同模型使用同一视图,我不建议这样做。在不同的情况下,我的意思是本质上确实有所不同,而不仅仅是“跟随”主模型的JUnit测试类。


1

我相信这没有硬性规定,这完全取决于您的需求。

您会发现有不同信仰的人。架构是帮助设计更好的解决方案的概念。

除了模型视图通信之外,关于MVC中的业务逻辑还有另一个矛盾。许多人认为所有业务逻辑都应该是一个模型(请参阅此SO问题),另一方面,弗洛里安(在他的回答中)共享的链接表示业务逻辑应该在控制器上。

除此之外,还可以将业务逻辑分为应用程序逻辑(将其放置在控制器上)和域登录(将其放置在模型上)。

因此,故事的寓意是MVC意味着模型,视图和控制器应该分开。除此之外,什么都最适合您。


0

我使用DTO进行模型视图通信。

例如:

  • 用户填写更新表格(视图)
  • 用户发送表格
  • 控制器将表单数据绑定到UserUpdateDTO
    • DTO和UserModel是POJO,但DTO没有ID和用户名,因为我们无法更新用户名。
    • 另一个区别是Model类具有关系和关联,但是DTO仅存储数据,我们可以在其中添加JSR 303验证器
  • 控制器说到服务层保存
  • 服务层对DAO层说以保留数据

-1

我同意这一说法,即视图永远不应该与模型进行通信。控制器必须始终是所有事物的首选,然后决定要做什么(验证,从模型中请求数据等)。

我倾向于将其更多地视为组织问题。


-1

关于为什么以及如何在不同的上下文中自由交互视图和模型的建议很多,但是在iOS中使Controller成为它们之间的中介者的主要原因是避免代码库中的Model&View依赖关系,并允许我们重用随着iOS的发展,可以根据要求进行建模或查看。

由于我们可能需要在UI / UX或模型中或同时在这两者中保持对应用程序的更新,因此它不应在模型和视图之间生成模式依赖代码。如果要更改应用程序的Presentation层,则只需转到更改它,您仍然可以重用相同的模型,反之亦然。

虽然我同意iOS中的MVC会产生巨大的ViewController,其中包含多种逻辑,并能处理除预期用途之外的所有其他事情,所以最好与MVVM或Presentation Controls搭配使用,以使您的代码库更灵活,更轻松以较小的ViewController读取和维护。

这可能会帮助正在iOS中寻找较小ViewController的人:

http://blog.xebia.com/simplification-of-ios-view-controllers-mvvm-or-presentation-controls/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.