20

早些时候,许多开发人员认为视图不应该像大多数框架那样直接与模型通信。

然后,这个观点似乎是错误的,我找了一些文章,这些文章说视图可以直接与模型通信。

http://r.je/views-are-not-templates.html
http://www.tonymarston.net/php-mysql/model-view-controller.html
模型、视图、控制器混淆
以及
模型应该如何在 MVC 中结构化?

这些文章中的大多数都引用了维基百科的一个块,模型-视图-控制器,引用是:

视图查询模型以生成适当的用户界面(例如,视图列出了购物车的内容)。视图从模型中获取自己的数据。在一些实现中,控制器可以向视图发出一般指令以呈现其自身。在其他情况下,需要屏幕更新的状态变化模型(观察者)会自动通知视图。

啊,来自wikipedia,这么权威的网站,一定是对的!

但是现在,当我打开MVC http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller的wiki链接时,页面已经编辑在今年9月14日(当年2013),上面的句子已经消失了。

视图的新定义是:

视图通过控制器从模型请求它需要生成输出表示给用户的信息。

现在我再次感到困惑,新定义说视图应该通过控制器从模型请求数据......

视图访问模型应该直接在地球上吗?

4

4 回答 4

24

以下是经典 MVC 架构中依赖关系的表示。您会注意到没有从控制器指向视图的箭头,因为它是新添加的:

在此处输入图像描述
Source: GUI architectures

然后有一个更接近于您通常在“MVC 框架”中看到的依赖关系图:

被动视图
Source: Passive view

“被动视图”配置不是MVC 架构的一部分。虽然它使用相同的名称,但它实际上是MVP模式的一种变体(您可以在本出版物中找到更长更详细的描述)

底线:是的,如果您正在实现 MVC 或类似 MVC 的架构,那么您的视图应该从模型层请求信息。

另外,您应该注意,这不是所谓的“mvc 框架”所追求的。在类 Rails 框架中没有视图。相反(因为原始结构是为原型设计的)视图被替换为哑模板,视图的所有职责都被推送到他们称之为“控制器”的东西中。

基本上,恕我直言,命名类 Rails 模式的最佳方式是OLT:ORM-Logic-Template。

于 2013-09-18T13:24:23.067 回答
16

“模型”是您的核心应用程序。您的应用程序可以做的一切都在模型中。
“视图”用于可视化正在发生的事情并提供用户界面。
“控制器”是对事件做出反应并指示模型和查看要做什么所需的粘合剂。

现在,对于模型和视图之间的通信,您有哪些选择?

  1. 推送:视图需要的所有数据都被推送到其中,通常由控制器推送。
  2. 拉取:视图从它自己需要的地方获取它需要的所有数据。

第二个显然更加独立。如果您需要将数据推送到视图中,这意味着视图之外的人需要知道视图想要什么。尤其是视图可以是非常动态的并且经常变化。有人决定在右上角再显示一个小部件,突然视图需要更多数据。这意味着需要重新编码其他部分才能将更多数据推送到视图中。所以你需要改变至少两个独立的部分,因为视图被改变了。

更好的选择是给视图一个句柄,允许它与模型对话并获取它自己需要的所有数据。控制器只是告诉视图“我们现在需要表单 XYZ,这是一个与模型对话的句柄,开始吧!” 并且视图可以完成它的工作。

于 2013-09-18T13:10:17.697 回答
1

我认为人们已经把概念、术语和实践搞得一团糟,以至于很难沟通。

我知道 MVC 是表示层架构的一种形式,因此,它的组件不应该包含业务逻辑,除非出于某种原因你想在 UI 中复制一些特定的业务规则。我认为,当人们在 ASP MVC 等框架中的视图模型类中填充(大部分)业务逻辑之类的东西时,问题就出现了(他们声称 MVC 不禁止这样做,但我确信他们忽略了正确的分层确实...)。

然后他们的业务层与视图模型合并,从而与表示层合并......

如果您想在项目中进行某种分层,我认为应该不惜一切代价避免这种情况。

至少,我对此的看法...

于 2014-11-10T16:28:13.800 回答
0

我认为围绕 MVC 的大多数引用通常都可以,但我假设您正在谈论......让我们具体并实际称它为......Microsoft View Controller。因为他们倾向于总是添加自己的一点点(虽然很多人不同意,但在我看来,我认为在大多数情况下他们的意图是很好的,但这是另一个话题的辩论)。

我只是想强调一下,Microsoft-View-Controller 实际上是 Model-View-Controller 主题的不同变体。

我的使用方式如下:

我通常使用各种模式来区分我的关注点,因为坦率地说……任何系统中最慢的部分之一是数据访问,紧随其后的是带宽。因此,我强烈认为将业务逻辑放入模型中是错误的,原因有两个:

  1. MVC(无论是什么变体)是一种设计为可扩展和可维护的开发方法。
  2. Microsoft-VC 中无法将视图连接到多个模型(除非您使用 ViewModels)。这种做法受到鼓励,并且与直接连接后端模型相关的安全问题比比皆是。不管是否需要,将视图直接连接到模型通常被认为是不好的做法,而您应该将它们与 ViewModel 连接起来。

MVC 是一种分层架构。所以分层。我的意思是让 EF 完成将您的表映射到类的工作,而不要管它。Microsoft-VC 通过使用“部分”类自动生成代码来强制人们将设计模式(打开/关闭原则)应用于模型。因此,您创建自己的空部分类,然后将元数据添加到其中。在此处添加代码不是一个好主意,因为它与模型紧密耦合。反而...

使用存储库模式添加存储库层。这使用你所有的模型类来做基本的(非常基本的)CRUD。然后...

添加域(业务)层,并使其调用 repo 层以获取执行业务规则所需的数据...然后...

仅将控制器连接到业务层,并使用 automapper 之类的工具将从域层返回的数据映射到视图的视图模型。

随着您在这方面的经验的增长,您可以稍后根据需要在层之间添加接口,并且很容易将众所周知的 IOC 模式与某种形式的 DI 一起应用。

希望这会有所帮助......但总的来说,MVC 是一种分层架构这一事实意味着添加层是它的设计目的,因此不要限制自己只使用一种方式。还请记住,如果您听到有人说 N 层多层架构适用于大型系统,那是无稽之谈……每个系统都是一个大型系统。没有一家企业可能会投资至少 100 万美元来开发一个小型系统并就此搁置(我知道,仅根据我的薪水和雇主必须支付的税款,我会获得很多钱来开发此类系统)我的薪水,我可以自信地说,任何雇用超过 2 名开发人员的公司已经远远超过了每年 10 万开发所谓的“小型”系统的成本)。

于 2014-10-10T09:29:18.240 回答