MVC: Model View Controller -- 视图是否调用模型?

7

我已经阅读了一段时间有关MVC设计的内容,官方说法是View调用Model中的对象和方法,构建并输出视图。

我认为这主要是错误的。

控制器应该在模型内部操作和检索/更新对象,选择合适的视图并将信息传递给它以便展示。只有简单的PHP变量/条件语句可以出现在视图中。

如果视图从模型中获取它需要展示的信息,那么视图中肯定会有很多PHP代码——完全违反了分离表示层逻辑的目的。

7个回答

10
与编程中的所有事物一样,我们需要务实。视图应仅包含呈现逻辑。该逻辑可以非常简单或相当复杂。只要该逻辑仅处理屏幕上显示的内容、打印在报告中等内容即可。
控制器应在模型内操作和检索/更新对象,选择适当的视图并将信息传递给它以便显示。
您传递的是什么信息?可能是模型的子集。您可以创建一个仅包含视图应了解的信息的新类,也可以仅传递模型并确保仅访问适当的数据。无论如何,视图应自由查询传入的模型以能够显示视图。
争议的焦点是,是否应从视图直接更新模型,绕过控制器。这就是务实的一面。我认为有些情况可以证明直接更新模型。特别是如果您可以使用数据绑定。然后,您可以将文本框分配给模型的属性,并让更新自动发生。如果有许多简单的属性设置,则此方法可以节省控制器中的大量代码。MVC不是一组铁板钉钉的规则。这是指导方针,正确使用时可以产生更好的代码,但如果使用过于严格,则可能会导致痛苦和苦难。
"务实一点!"

9

没有一种绝对正确的MVC实现方式,可以存在多种变体。

例如,除了让View主动查询Model外,Controller还可以使用某种通知机制通知View有关Model中任何更改。在这种情况下,View只是监听更新,然后呈现它们。


3
我认为这可能不是所谓的“纯”MVC,但只要视图PHP代码不改变模型,这并不是一个大问题。 MVC最重要的规则是模型不知道视图。使视图不知道模型的情况则不那么重要。直接使用模型的主要缺点是视图无法与不同的模型重复使用。这很少是一个问题,因为视图几乎总是特定于一种特定类型的模型对象(或其列表)。

2
以下对DisgruntledGoat代码片段的修改是否被认为太“复杂”?是否应将对象传递给视图?
<li><?=$item->description?></li>

或者呢?
<li><?=$item->getDescription()?></li>

我看过一些只使用数组的例子:-
<li><?=$item['description']?></li>

传递对象或变量只是一种设计偏好,但我更倾向于使用数组,因为并不是所有传递到视图的数据都已经以对象形式存在。我喜欢在我的视图中保持一致性,选择始终通过对象或数组进行传递。对于 getDescription(),我认为这取决于 getDescription 实际执行的操作。如果它仅使用帮助函数以复杂的方式格式化代码,则可以接受。但是,如果它导致进行 SQL 查询,那么这不是一个好主意;这是控制器从模型获取数据的工作。 - Gary Green
感谢回复。我在考虑控制器将数据作为对象传递给视图,而不是数组,然后 PHP 的“蔓延”复杂性(公共属性访问被方法替换)会增加,但建议保持 PHP 简单。 - Gammerz

1

我认为你是完全正确的 - 视图不应该调用模型中的方法。就像其他人所说,MVC有各种变化,但重点是将逻辑、数据和输出分离。

通常情况下,您需要一个控制器作为应用程序的起点。在PHP中,这将是您的index.php文件。至少,此文件将处理输入数据(即查询字符串或URL参数)。最好为应用程序的不同部分添加单独的控制器。

然后,每个控制器只需决定需要显示哪些数据,从模型中获取它,并将其传递给视图。在PHP中,您将调用各种类/方法从数据库中获取数据,并将其存储在变量中。

然后,您只需包含另一个PHP文件,其中包含大部分HTML,但带有一些PHP回显变量。循环也可以。如果您有一系列事物,您可能想要执行以下操作:

<ul>
<?php foreach ($items as $item) : ?>
  <li><?=$item?></li>
<?php endforeach; ?>
</ul>

1

MVC不是一成不变的法则。根据你阅读的来源,它可能会有所不同。就个人而言,我不允许视图直接从模型中读取。

更新 这篇文章也有一些很好的例子。模型是具有start()方法的汽车引擎,视图是具有paint()或change()方法的汽车颜色,控制器是驾驶员。我更喜欢让控制器驱动汽车并启动引擎,而不是让轮子或油漆来做。

:)


我认为将视图看作模板会更好。就像我喜欢看到的MVT(模型-视图-控制器)。从控制器检索信息并传递给视图的唯一缺点是,视图现在依赖于控制器。不能直接调用视图来显示页面,必须通过控制器--但另一方面,这正是控制器的整个目的-路由HTTP GET / POST请求。 - Gary Green
1
个人而言,我不允许视图直接从模型中读取。- 即使在使用AJAX的情况下呢? - Wouter Dorgelo
1
@Mr.Pallazzo同样如此。Ajax请求仍然由控制器处理,而不是直接由模型处理。从服务器的角度来看,在正常请求和Ajax请求之间在概念上没有区别。区别在于输出和客户端。 - Elzo Valugi

1
MVC指的是层,而不是组件。因此它们是更抽象的概念,而不是蓝图。由于完全分离这些层是不太可能的(信息必须在它们之间流动),所以实际上是一个连续体,在一个极端有意乱的系统,在另一个极端有官僚主义类型的系统。你可能想找到介于这两者之间的某个地方。
我通常不会花太多精力在控制器和视图之间的分离上。模型和(控制器-视图)之间的分离要重要得多。

将模型函数与控制器和视图分离非常重要,但我认为知道哪些内容属于模型相对比较直观;所有与数据、业务逻辑、验证等有关的事情。现在,在视图和控制器之间的界限上,你很容易就会陷入代码混乱的境地。 - Gary Green

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接