【问题标题】:MVC: should view talk with model directly?MVC:视图应该直接与模型对话吗?
【发布时间】:2013-09-18 13:01:13
【问题描述】:

之前,许多开发人员认为视图不应该直接与模型通信,就像大多数框架一样。

然后,这个观点好像是错误的,我找了一些文章,这些文章说view可以直接和model通信。

http://r.je/views-are-not-templates.html
http://www.tonymarston.net/php-mysql/model-view-controller.html
Model, View, Controller confusion

How should a model be structured in MVC?

这些文章大部分都引用了维基百科的一个块,Model-view-controller,引用是:

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

啊,来自维基百科,这么权威的网站,一定是对的!

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

视图的新定义是:

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

现在我又搞糊涂了,新定义说视图应该通过控制器从模型请求数据...

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

【问题讨论】:

  • 你应该在programmers.stackexchange.com问这个问题
  • 对不起,我在这个网站上发现了很多类似的话题,没有找到答案,所以我只是在这里发布......
  • @Cifer wiki 文章已修复。
  • @tereško 你刚才说维基文章的更改是破坏行为,为什么要编辑你的答案?您找到文章更改的适当原因了吗?
  • 因为那里有很多不好的信息。所有类似 Rails 的框架都使用术语“MVC”作为广告工具。你认为如果有人开始宣传他们正在使用极其愚蠢的PAC 版本,他们会被炒作吗?

标签: php model-view-controller


【解决方案1】:

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


来源:GUI architectures

还有一个更接近于你通常会在“MVC 框架”中看到的依赖图:


来源:Passive view

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

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

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

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

【讨论】:

  • 我想知道为什么维基百科改变了视图的定义......来带来MVC的新定义?
  • 维基百科不是单一的知识来源。所有的改变都不是人为的。有些人很愚蠢。
  • Fowler 将 MVC 称为 GUI 架构。如果这是正确的,那么说MVC的M是业务规则、数据、逻辑等,是不是错了?
  • @Maykonn 你能改写一下吗?我不知道你想问什么。
  • 什么是“域应用”?
【解决方案2】:

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

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

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

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

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

【讨论】:

  • 感谢您的回答!我从你那里学到了一些新观点。我想知道为什么维基百科改变了视图的定义......
  • @deceze 您的声明控制器只是告诉视图“我们现在需要表单 XYZ,这是与模型对话的句柄,开始吧!”。我从没想过控制器将模型的句柄传递给视图。你加深了我对MVC的理解!谢谢!
  • 关于视图,您能否举一个“允许它与模型对话的句柄”的示例?另外,视图不应该能够自己请求和显示来自域模型的数据吗?例如。视图不应该拥有自己的句柄吗?为什么控制器会向视图传递一些东西,比如句柄?谢谢。 P.S:您的答案是否仍然是最新的?如果没有,我会对你目前的观点非常感兴趣。
  • @dakis 一个词:依赖注入。这主要是我所说的“处理”。当然这不是绝对必要的,但 IMO 是个好主意。
  • 对不起,我会坚持一点:1) 所以 " 给视图一个句柄" 你的意思是,例如,向视图注入服务,视图通过它获取它需要显示的模型数据?还是我误解了什么? 2)控制器如何以及为什么参与其中? 3)如果你不介意,一小段代码会很棒。
【解决方案3】:

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

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

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

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

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

【讨论】:

    【解决方案4】:

    我认为围绕 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 层多层架构适用于大型系统,那是无稽之谈……每个系统都是一个大型系统。没有一家企业可能会投资至少数千美元来开发一个小型系统,然后就任其发展(我知道,仅根据我的薪水和雇主必须支付的税款,我就获得了很多钱来开发此类系统我的薪水,我可以自信地说,任何雇用超过 2 名开发人员的公司已经远远超过了每年 10 万开发所谓的“小型”系统的成本)。所有系统都旨在增长,您越早采用这种方法,您的系统就越容易维护和扩展。

    【讨论】:

      猜你喜欢
      • 2012-10-21
      • 1970-01-01
      • 2016-03-04
      • 2013-11-17
      • 2015-06-11
      • 2015-03-13
      • 1970-01-01
      • 2011-04-14
      • 2021-07-27
      相关资源
      最近更新 更多