Java 什么进入“MVC”中的“控制器”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1015813/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 22:18:28  来源:igfitidea点击:

What goes into the "Controller" in "MVC"?

javamodel-view-controller

提问by Paul Walker

I think I understand the basic concepts of MVC - the Model contains the data and behaviour of the application, the View is responsible for displaying it to the user and the Controller deals with user input. What I'm uncertain about is exactly whatgoes in the Controller.

我想我理解 MVC 的基本概念——模型包含应用程序的数据和行为,视图负责向用户显示它,控制器处理用户输入。我不确定的是控制器中到底发生了什么

Lets say for example I have a fairly simple application (I'm specifically thinking Java, but I suppose the same principles apply elsewhere). I organise my code into 3 packages called app.model, app.viewand app.controller.

例如,我有一个相当简单的应用程序(我特别考虑 Java,但我认为相同的原则适用于其他地方)。我将我的代码组织成 3 个包,称为app.model,app.viewapp.controller.

Within the app.modelpackage, I have a few classes that reflect the actual behaviour of the application. These extends Observableand use setChanged()and notifyObservers()to trigger the views to update when appropriate.

app.model包中,我有几个类反映了应用程序的实际行为。这些extends Observable并使用setChanged()notifyObservers()触发视图在适当的时候更新。

The app.viewpackage has a class (or several classes for different types of display) that uses javax.swingcomponents to handle the display. Some of these components need to feed back into the Model. If I understand correctly, the View shouldn't have anything to do with the feedback - that should be dealt with by the Controller.

app.view包有一个类(或多个用于不同类型显示的类),它使用javax.swing组件来处理显示。其中一些组件需要反馈到模型中。如果我理解正确,视图不应该与反馈有关 - 这应该由控制器处理。

So what do I actually put in the Controller? Do I put the public void actionPerformed(ActionEvent e)in the View with just a call to a method in the Controller? If so, should any validation etc be done in the Controller? If so, how do I feedback error messages back to the View - should that go through the Model again, or should the Controller just send it straight back to View?

那么我实际上在控制器中放了什么?我是否public void actionPerformed(ActionEvent e)只需调用控制器中的方法即可将其放入视图中?如果是这样,是否应该在控制器中进行任何验证等?如果是这样,我如何将错误消息反馈回视图 - 应该再次通过模型,还是控制器应该直接将其发送回视图?

If the validation is done in the View, what do I put in the Controller?

如果验证是在 View 中完成的,我在 Controller 中放什么?

Sorry for the long question, I just wanted to document my understanding of the process and hopefully someone can clarify this issue for me!

抱歉问了这么长的问题,我只是想记录一下我对这个过程的理解,希望有人能帮我澄清这个问题!

采纳答案by Andres Jaan Tack

In the example you suggested, you're right: "user clicked the 'delete this item' button" in the interface should basically just call the controller's "delete" function. The controller, however, has no idea what the view looks like, and so your view must collect some information such as, "which item was clicked?"

在您建议的示例中,您是对的:界面中的“用户单击了‘删除此项目’按钮”应该基本上只是调用控制器的“删除”功能。然而,控制器不知道视图是什么样子,因此您的视图必须收集一些信息,例如“点击了哪个项目?”

In a conversation form:

以对话形式:

View: "Hey, controller, the user just told me he wants item 4 deleted."
Controller: "Hmm, having checked his credentials, he is allowed to do that... Hey, model, I want you to get item 4 and do whatever you do to delete it."
Model: "Item 4... got it. It's deleted. Back to you, Controller."
Controller: "Here, I'll collect the new set of data. Back to you, view."
View: "Cool, I'll show the new set to the user now."

视图:“嘿,控制器,用户刚刚告诉我他想要删除第 4 项。”
管制员:“嗯,在检查了他的凭据后,他被允许这样做......嘿,模型,我想让你拿到第 4 项,然后尽你所能删除它。”
模型:“项目 4 ......明白了。它被删除了。回到你身边,控制器。”
控制者:“来,我会收集新的数据集。返回给你,查看。”
视图:“很酷,我现在就向用户展示新的集合。”

In the end of that section, you have an option: either the view can make a separate request, "give me the most recent data set", and thus be more pure, or the controller implicitly returns the new data set with the "delete" operation.

在该部分的末尾,您有一个选择:视图可以发出单独的请求,“给我最新的数据集”,从而更加纯净,或者控制器隐式地返回带有“删除”的新数据集“ 手术。

回答by David Seiler

As I understand it, the Controller translates from user-interface actions to application-level actions. For instance, in a video game the Controller might translate "moved the mouse so many pixels" into "wants to look in such and such a direction. In a CRUD app, the translation might be "clicked on such and such a button" to "print this thing", but the concept is the same.

据我了解,控制器从用户界面操作转换为应用程序级操作。例如,在视频游戏中,控制器可能将“将鼠标移动了这么多像素”翻译成“想要朝某个方向看。在 CRUD 应用程序中,翻译可能是“点击某某按钮”以“打印这个东西”,但概念是一样的。

回答by JP Alioto

Here is a good articleon the basics of MVC.

这是一篇关于MVC基础知识的好文章

It states ...

它指出 ...

Controller - The controller translates interactions with the view into actions to be performed by the model.

控制器 - 控制器将与视图的交互转换为模型要执行的操作。

In other words, your business logic. The controller responds to actions by the user taken the in the view and responds. You put validation here and select the appropriate view if the validation fails or succeeds (error page, message box, whatever).

换句话说,您的业务逻辑。控制器响应用户在视图中采取的操作并做出响应。如果验证失败或成功(错误页面、消息框等),您将验证放在这里并选择适当的视图。

There is another good article at Fowler.

Fowler 上还有另一篇文章

回答by Jon

The controller is primarily for co-ordination between the view and the model.

控制器主要用于视图和模型之间的协调。

Unfortunately, it sometimes ends up being mingled together with the view - in small apps though this isn't too bad.

不幸的是,它有时最终会与视图混合在一起 - 在小应用程序中虽然这还不错。

I suggest you put the:

我建议你把:

public void actionPerformed(ActionEvent e)

in the controller. Then your action listener in your view should delegate to the controller.

在控制器中。然后您视图中的动作侦听器应委托给控制器。

As for the validation part, you can put it in the view or the controller, I personally think it belongs in the controller.

至于验证部分,可以放在view或者controller里面,我个人认为属于controller。

I would definitely recommend taking a look at Passive View and Supervising Presenter (which is essentially what Model View Presenter is split into - at least by Fowler). See:

我绝对会推荐看一看 Passive View 和 Supervising Presenter(这本质上是 Model View Presenter 被拆分的部分——至少是 Fowler)。看:

http://www.martinfowler.com/eaaDev/PassiveScreen.html

http://www.martinfowler.com/eaaDev/PassiveScreen.html

http://www.martinfowler.com/eaaDev/SupervisingPresenter.html

http://www.martinfowler.com/eaaDev/SupervisingPresenter.html

回答by BlairHippo

Based on your question, I get the impression that you're a bit hazy on the role of the Model. The Model is fixated on the data associated with the application; if the app has a database, the Model's job will be to talk to it. It will also handle any simple logic associated with that data; if you have a rule that says that for all cases where TABLE.foo == "Hooray!" and TABLE.bar == "Huzzah!" then set TABLE.field="W00t!", then you want the Model to take care of it.

根据你的问题,我觉得你对模特的角色有点模糊。模型专注于与应用程序相关的数据;如果应用程序有一个数据库,模型的工作就是与它对话。它还将处理与该数据相关的任何简单逻辑;如果你有一个规则,对于所有 TABLE.foo == "Hooray!" 的情况 和 TABLE.bar == "Huzzah!" 然后设置 TABLE.field="W00t!",然后您希望模型处理它。

The Controller is what should be handling the bulk of the application's behavior. So to answer your questions:

控制器应该处理大部分应用程序的行为。所以回答你的问题:

"Do I put the public void actionPerformed(ActionEvent e) in the View with just a call to a method in the Controller?"

“我是否只需调用控制器中的方法就可以将 public void actionPerformed(ActionEvent e) 放在 View 中?”

I'd say no. I'd say that should live in the Controller; the View should simply feed the data coming from the user interface into the Controller, and let the Controller decide which methods ought to be called in response.

我会说不。我会说它应该存在于控制器中;视图应该简单地将来自用户界面的数据提供给控制器,并让控制器决定应该调用哪些方法作为响应。

"If so, should any validation etc be done in the Controller?"

“如果是这样,是否应该在控制器中进行任何验证等?”

The bulk of your validation really ought to be done by the Controller; it should answer the question of whether or not the data is valid, and if it isn't, feed the appropriate error messages to the View. In practice, you may incorporate some simple sanity checks into the View layer for the sake of improving the user experience. (I'm thinking primarily of web environments, where you might want to have an error message pop up the moment the user hits "Submit" rather than wait for the whole submit -> process -> load page cycle before telling them they screwed up.) Just be careful; you don't want to duplicate effort any more than you have to, and in a lot of environments (again, I'm thinking of the web) you often have to treat any data coming from the user interface as a pack of filthy filthy lies until you've confirmed it's actually legitimate.

您的大部分验证确实应该由控制器完成;它应该回答数据是否有效的问题,如果不是,则将适当的错误消息提供给视图。在实践中,为了改善用户体验,您可能会在 View 层中加入一些简单的健全性检查。(我主要考虑 Web 环境,您可能希望在用户点击“提交”时弹出错误消息,而不是等待整个提交 -> 处理 -> 加载页面周期,然后再告诉他们他们搞砸了.) 小心点;您不想重复工作,并且在很多环境中(再次,我想到网络),您经常不得不将来自用户界面的任何数据视为一堆肮脏的污秽撒谎直到你”

"If so, how do I feedback error messages back to the View - should that go through the Model again, or should the Controller just send it straight back to View?"

“如果是这样,我如何将错误消息反馈回视图 - 应该再次通过模型,还是控制器应该直接将其发送回视图?”

You should have some protocol set up where the View doesn't necessarily know what happens next until the Controller tells it. What screen do you show them after the user whacks that button? The View might not know, and the Controller might not know either until it looks at the data it just got. It could be "Go to this other screen, as expected" or "Stay on this screen, and display this error message".

您应该设置一些协议,其中视图不一定知道接下来会发生什么,直到控制器告诉它。在用户敲击该按钮后,您会向他们显示什么屏幕?View 可能不知道,Controller 也可能不知道,直到它查看刚刚获得的数据。它可能是“按预期转到另一个屏幕”或“停留在此屏幕上,并显示此错误消息”。

In my experience, direct communication between the Model and the View should be very, very limited, and the View should not directly alter any of the Model's data; that should be the Controller's job.

根据我的经验,Model 和 View 之间的直接通信应该非常非常有限,并且 View 不应该直接改变 Model 的任何数据;那应该是控制器的工作。

"If the validation is done in the View, what do I put in the Controller?"

“如果验证是在视图中完成的,我在控制器中放什么?”

See above; the real validation should be in the Controller. And hopefully you have some idea of what should be put in the Controller by now. :-)

看上面; 真正的验证应该在控制器中。并且希望您现在对应该在 Controller 中放置的内容有所了解。:-)

It's worth noting that it can all get a little blurry around the edges; as with most anything as complex as software engineering, judgment calls will abound. Just use your best judgment, try to stay consistent within this app, and try to apply the lessons you learn to the next project.

值得注意的是,它的边缘都会变得有点模糊;与大多数像软件工程这样复杂的事情一样,判断力会比比皆是。只需运用您的最佳判断力,尝试在此应用程序中保持一致,并尝试将您学到的经验教训应用到下一个项目中。

回答by John Kugelman

Practically speaking, I've never found the controller concept to be a particularly useful one. I use strict model/view separation in my code but there's no clearly-defined controller. It seems to be an unnecessary abstraction.

实际上,我从来没有发现控制器概念是一个特别有用的概念。我在代码中使用了严格的模型/视图分离,但没有明确定义的控制器。这似乎是一种不必要的抽象。

Personally, full-blown MVC seems like the factory design pattern in that it easily leads to confusing and over-complicated design. Don't be an architecture astronaut.

就个人而言,成熟的 MVC 似乎是工厂设计模式,因为它很容易导致设计混乱和过于复杂。不要成为建筑宇航员

回答by akf

also note that each Swing widget is can be considered to contain the three MVC components: each has a Model (ie ButtonModel), a View (BasicButtonUI), and a Control (JButton itself).

还要注意,每个 Swing 小部件都可以被认为包含三个 MVC 组件:每个组件都有一个模型(即 ButtonModel)、一个视图(BasicButtonUI)和一个控件(JButton 本身)。

回答by staticsan

Here is a rule of thumb that I use: if it is a procedure that I will be using specificallyfor an action on thispage, it belongs in the controller, not the model. The model should provide only a coherent abstraction to the data storage.

这是我使用的经验法则:如果这是我将专门用于页面上的操作的过程,则它属于控制器,而不是模型。该模型应仅提供对数据存储的一致抽象。

I've come up with this after working with a large-ish webapp written by developers who thought they were understood MVC but really didn't. Their "controllers" are reduced to eight lines of calling static class methods that are usuall called nowhere else :-/ making their models little more than ways of creating namespaces. Refactoring this properly does three things: shifts all the SQL into the data access layer (aka model), makes the controller code a bit more verbose but a lot more understandable, and reduces the old "model" files to nothing. :-)

在使用了一个由开发人员编写的大型 web 应用程序后,我想出了这个,他们认为他们理解 MVC 但实际上没有。他们的“控制器”减少到八行调用静态类方法,这些方法通常在别处调用:-/使他们的模型只不过是创建命名空间的方法。正确重构它可以做三件事:将所有 SQL 转移到数据访问层(又名模型),使控制器代码更冗长但更易于理解,并将旧的“模型”文件减少到零。:-)

回答by mnuzzo

You are essentially right about what you put in the controller. It is the only way the Model should interact with the View. The actionperformed can be placed in the View, but the actual functionality can be placed in another class which would act as the Controller. If you're going to do this, I recommend looking into the Command pattern, which is a way of abstracting all of the commands that have the same receiver. Sorry for the digression.

您在控制器中放入的内容基本上是正确的。这是模型与视图交互的唯一方式。执行的动作可以放在视图中,但实际功能可以放在另一个充当控制器的类中。如果您打算这样做,我建议您查看命令模式,这是一种抽象具有相同接收器的所有命令的方法。抱歉跑题了。

Anyway, a proper MVC implementation will have the following interactions only: Model -> View View -> Controller Controller -> View

无论如何,一个合适的 MVC 实现只会有以下交互:模型 -> 视图视图 -> 控制器控制器 -> 视图

The only place where there may be another interaction is if you use an observer to update the View, then the View will need to ask the Controller for the information it needs.

唯一可能存在其他交互的地方是,如果您使用观察者来更新视图,那么视图将需要向控制器询问它需要的信息。

回答by duffymo

Controller is really part of the View. Its job is to figure out which service(s) are needed to fulfill the request, unmarshal values from the View into objects that the service interface requires, determine the next View, and marshal the response back into a form that the next View can use. It also handles any exceptions that are thrown and renders them into Views that users can understand.

控制器实际上是视图的一部分。它的工作是找出需要哪些服务来满足请求,将 View 中的值解组为服务接口所需的对象,确定下一个 View,并将响应编组回下一个 View 可以使用的形式. 它还处理抛出的任何异常并将它们呈现到用户可以理解的视图中。

The service layer is the thing that knows the use cases, units of work, and model objects. The controller will be different for each type of view - you won't have the same controller for desktop, browser-based, Flex, or mobile UIs. So I say it's really part of the UI.

服务层是知道用例、工作单元和模型对象的东西。每种类型的视图的控制器都不同——桌面、基于浏览器、Flex 或移动 UI 的控制器不会相同。所以我说它真的是用户界面的一部分。

Service-oriented: that's where the work is done.

以服务为导向:这就是工作完成的地方。