具体来说,什么属于模型、视图和控制器?
我一直在学习模型-视图-控制器范例(“MVC”),但我很困惑,因为有些教程与其他教程相矛盾。
我目前对该过程的理解是这样的:
Router / Dispatcher / Front Controller:
- 虽然没有在“MVC”名称中具体引用,但 Router 仍然是一个非常重要的部分。正是在这里,请求从原始 URL 转换到特定的控制器。例如,将对 www.StackUnderflow.com/question/123 的请求路由到应用程序的“问题”控制器。
模型:
这是从某些存储源(例如数据库或 XML 文件)收集原始数据的位置。该模型充当抽象层,将控制器对特定数据的请求转换为(例如)SQL 查询,并将查询结果转换为数据对象等标准格式。
例如,在上述 /browse/all 场景中:
- “问题”控制器会询问模型“请提供问题 123 的数据。”
- 模型会将其翻译为“SELECT * FROM Questions WHERE Id = 123;”并将其存入数据库
- 数据库将向模型返回一个“问题”记录。
- 模型将获取记录,并将其转换为问题数据对象
- 模型然后要求做同样的事情“SELECT * FROM Answers WHERE QuestionID = 123;”并从结果集中创建一个 Answer 对象数组,并将其添加到 Question 对象的answers 成员变量中。
- 模型会将问题对象返回到“问题”控制器。
控制器:
这是应用程序的真正主力。除了将消息来回转发到模型和视图之外,控制器还负责诸如授权
和应用程序之类的事情/“业务”逻辑编辑:根据答案,业务逻辑属于模型。在当前示例中,控制器将负责:
- 确保用户已登录。
- 从 URL 确定 QuestionId。
- 确定要使用的视图。
- 发送 HTTP 代码并根据需要进行重定向。
- 向模型请求数据,并将所需数据存储在成员变量中。
视图:
- 总的来说,视图是应用程序中最简单的部分。它在基本应用程序中主要由 HTML 模板组成。这些模板将具有占位符,用于将数据从控制器的成员变量插入到模板中:
例如,
<html>
<head>
<title>
<?php $question->getTitle() ?>
</title>
</head>
<body>
<h1> <?php $question->getQuestionText(); ?> </h1>
<h2> Answers: </h2>
<div class="answerList">
<?php formatAnswerList($question->getAnswers()); ?>
</div>
</body>
</html>
- 视图还将包含格式化数据以交付给用户的方法。例如,上面的
formatAnswerList()
方法将获取从 Controller 获取的答案数组,并在调用诸如include $markupPath 之类的方法时循环遍历它们。 “/formatAnswer.inc”
这将是一个答案容器的小模板。
问题:
- 这种 MVC 观点从根本上来说是准确的吗?
- 如果没有,请仔细解释哪些组件被放错了位置,它们实际上应该放在哪里,以及它们应该如何与其他组件正确交互(如果有的话)。
- 有多少个类来描述这个?在我的示例中,有四个对象 - 一个对象对应 MVC 的三个组件,另一个对象仅存储用于传输的相关数据。这是正常现象吗,还是应该将某些情况结合起来。如果有,是哪些?
I've been learning about the Model-View-Controller paradigm ("MVC"), but I'm quite confused since some tutorials contradict other tutorials.
My current understanding of the process looks something like this:
Router / Dispatcher / Front Controller:
- Though not specifically referenced in the "MVC" name, the Router is still a very important part. It is here that requests are translated from raw URLs to a specific controller. For example, routing a request for www.StackUnderflow.com/question/123 to the "Question" Controller of the application.
Model:
This is where raw data is collected from some storage source, such as a database or XML file. The model serves as an abstraction layer, translating the Controller's request for specific data into (for example) an SQL query, and translating the query results into a standard format like a data object.
For example, in the /browse/all scenario stated above:
- The "Question" Controller would ask the Model "Please give the data for question 123."
- The Model would then translate that into "SELECT * FROM Questions WHERE Id = 123;" and punt it to the database
- The database would return a "Question" record to the Model.
- The Model would take the record, and translate it into a Question data object
- The Model then asks does the same thing "SELECT * FROM Answers WHERE QuestionID = 123;" and creates an array of Answer objects from the resultset, and adds that to the Question object's answers member variable.
- The Model would return the Question object to the "Question" Controller.
Controller:
This is the real workhorse of the application. In addition to relaying messages back and forth to the Model and the View, the Controller is also responsible for things like Authorization
and application/"business" logicEdit: Per answer, business logic belongs in the Model.In the ongoing example, the Controller wold be responsible for:
- Ensuring the user is logged in.
- Determining the QuestionId from the URL.
- Determining which View to use.
- Sending HTTP codes and redirecting if needed.
- Asking the Model for data, and store needed data in member variables.
View:
- By and large, the View is the simplest part of the application. It mostly consists, in a basic application, of HTML templates. These templates would have placeholders to insert data into the template from the Controller's member variables:
e.g.
<html>
<head>
<title>
<?php $question->getTitle() ?>
</title>
</head>
<body>
<h1> <?php $question->getQuestionText(); ?> </h1>
<h2> Answers: </h2>
<div class="answerList">
<?php formatAnswerList($question->getAnswers()); ?>
</div>
</body>
</html>
- The View would also contain methods to format data for delivery to the user. For example, the
formatAnswerList()
method above would take an array of answers, taken from the Controller, and loop through them while calling something likeinclude $markupPath . "/formatAnswer.inc"
which would be a small template of just an answer container.
Questions:
- Is this view of MVC fundamentally accurate?
- If not, please carefully explain which components are misplaced, where they should actually go, and how they should properly interact with the other components (if at all).
- How many classes are used to describe this? In my example there are four objects - one each for the three components of MVC and one that simply stores related data for transmission. Is this normal, or should some be combined. If so, which ones?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为这个描述对控制器的重视程度过高,而对模型的重视程度不够。理想情况下,模型是业务逻辑所在的位置。控制器实际上只是站点用户的一个界面,将控制路由到需要去的地方。看一下之前关于该主题的讨论:
理解 MVC:模型上的“胖”、控制器上的“瘦”是什么概念?
I think this description puts too much weight on the controller and not enough on the model. The model is ideally where the business logic resides. The controller is really just an interface for the user of the site, routing control where it needs to go. Take a look at a previous discussion on the topic:
Understanding MVC: Whats the concept of "Fat" on models, "Skinny" on controllers?
本质上,一切都在正确的位置。
在您的示例中,您定义了一个 Question 类 - 称为 ViewModel,它只是一个容器,用于容纳要在视图中使用/从视图中检索的所有数据。
在某些情况下,我看到 ViewModel 被忽略,而 Model 被传递给 View - 当我第一次查看教程时,这让我很困惑,而且我不喜欢省略 ViewModel,我认为这会让事情变得混乱。
Essentially you have everything in the right place.
In your example you define a Question class - which would be known as a ViewModel, simply a container for all the data that is to be used in the View/ retrieved from the View.
In some cases I have seen the ViewModel overlooked and the Model is passed to the View - this confused me when I was first looking at tutorials, and I don't like omitting the ViewModel, I think it confuses things.