MVC:应该直接查看与模型的对话吗?

时间:2013-09-18 13:01:13

标签: php model-view-controller

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

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

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?

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

  

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

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

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

视图的新定义是:

  

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

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

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

4 个答案:

答案 0 :(得分:21)

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

enter image description here
来源:GUI architectures

然后有依赖关系图更接近你在“MVC框架”中通常会看到的内容:

Passive View
来源:Passive view

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

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

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

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

答案 1 :(得分:13)

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

现在,您对模型和视图之间的通信有什么选择?

  1. 推送:通常由控制器将视图所需的所有数据推入其中。
  2. 拉:视图从需要的地方获取所需的所有数据。
  3. 第二个显然更加独立。如果您需要将数据推送到视图中,这意味着视图外的某个人需要知道视图需要什么。尤其是视图可以非常动态并且经常变化。有人决定在右上角再显示一个小部件,突然之间视图需要更多数据。这意味着需要重新编码其他部分以将更多数据推送到视图中。因此,您需要更改至少两个独立的部分,因为视图已被更改。

    更好的选择是为视图提供一个句柄,使其能够与模型通信并获取自己需要的所有数据。控制器只是告诉视图“我们现在需要表单XYZ,这里是一个与模型对话的句柄,去吧!”并且视图可以完成它的工作。

答案 2 :(得分:1)

我认为人们已经弄乱了概念,术语和实践,因此很难沟通。

我知道MVC是表示层体系结构的一种形式,因此,除非出于某种原因要在UI中复制某些特定的业务规则,否则其组件不应包含业务逻辑。我认为,当人们把像(大多数)业务逻辑这样的东西放在像ASP MVC这样的框架中的视图模型类中时,问题就出现了(他们声称MVC并没有禁止这一点,但我确信他们忽略了正确的分层确实...)。

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

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

至少,我对此有所了解......

答案 3 :(得分:0)

我认为MVC周围的大多数引用一般都可以,但我会假设你正在谈论......让我们具体一点,实际上称之为...... Microsoft View Controller。因为他们往往总是添加自己的一点点(虽然许多人不同意,但在我看来,我认为他们的意图很大程度上已形成,但这是另一个话题的争论。)

我只是想强调,Microsoft-View-Controller实际上是模型 - 视图 - 控制器主题的另一种变体。

我使用它的方式如下:

我通常会使用各种模式来区分我的顾虑,因为我们可以直言不讳......任何系统中最慢的部分之一就是数据访问,其次是带宽。所以我强烈认为,通过将业务逻辑放在模型中做出许多建议有两个原因:

  1. MVC(无论变体)是一种旨在可扩展和可维护的开发方法。
  2. Microsoft-VC无法将视图连接到多个模型(除非您使用ViewModels)。鼓励这种做法,并且与直接连接后端模型有关的安全问题比比皆是。无论是否需要,将视图直接连接到模型通常被认为是不好的做法,而应将它们与ViewModels连接起来。
  3. MVC是一种分层架构。所以分层吧。通过这个我的意思是让EF完成将表映射到类的工作并让它不管它。 Microsoft-VC强制人们通过使用“部分”类自动生成代码,将设计模式(打开/关闭原则)应用于模型。因此,您创建自己的空部分类,然后将元数据添加到此。在这里添加代码并不是一个好主意,因为它与模型紧密耦合。代替...

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

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

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

    随着您对此经验的增长,您可以根据需要在层之间添加界面,并且可以轻松应用具有某种形式DI的众所周知的IOC模式。

    希望这会有所帮助......但总的来说,MVC是一个分层架构的事实意味着添加图层就是它的设计目的,所以不要仅限于使用单向工作。还要记住,如果你听到有人说N-Tier多层架构适用于大型系统,那么这只是废话......每个系统都是一个大系统。没有企业可以投资至少100个成千上万来开发一个小型系统并将其留下(我知道我得到了很多钱来开发这样的系统,基于我的工资和雇主必须支付的税金我的工资,我可以充满信心地说,任何雇用超过2名开发人员的公司已经远远超过了每年100K开发所谓的“小型”系统的成本。所有系统都旨在增长,越早采用这种方法,您的系统就越容易维护和扩展。