当前位置:  开发笔记 > 编程语言 > 正文

什么进入"MVC"的"控制器"?

如何解决《什么进入"MVC"的"控制器"?》经验,为你挑选了7个好方法。

我想我理解MVC的基本概念 - 模型包含应用程序的数据和行为,View负责将其显示给用户,Controller负责处理用户输入.我不确定的是控制器中究竟是什么.

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

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

app.view包具有一个类(或几个类用于不同类型的显示),它使用javax.swing组件来处理显示.其中一些组件需要反馈到模型中.如果我理解正确,View不应该与反馈有任何关系 - 应该由Controller处理.

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

如果在视图中完成验证,我应该在Controller中添加什么?

很抱歉这个问题很长,我只想记录我对这个过程的理解,希望有人可以为我澄清这个问题!



1> Andres Jaan ..:

在您建议的示例中,您说得对:"用户点击界面中的'删除此项'按钮'基本上只需调用控制器的"删除"功能.但是,控制器不知道视图的样子,因此您的视图必须收集一些信息,例如"单击了哪个项目?"

在对话形式中:

查看:"嘿,控制器,用户只是告诉我他想要删除第4项."
控制器:"嗯,检查了他的证书,他被允许这样做......嘿,模特,我希望你得到第4项并做任何你做的删除它."
型号:"第4项......得到它.它被删除.回到你身边,控制器."
控制器:"在这里,我将收集新的数据集.回到你身边,查看."
查看:"很酷,我现在将向用户展示新的设置."

在该部分的末尾,您有一个选项:视图可以发出单独的请求,"给我最新的数据集",因此更纯粹,或者控制器通过"删除"隐式返回新数据集"操作.


那次对话是对我遇到的MVC的最好解释,谢谢!
一切都很好,但直接从模型中读取*读取*没有任何问题."控制器不是数据警察".还有一种学说可以保持控制器的薄弱.View Helpers是收集数据的理想场所,可供您的视图使用.不应该分配完整的控制器堆栈来重用一些数据访问逻辑.更多细节:http://www.rmauger.co.uk/2009/03/why-the-zend-framework-actionstack-is-evil/#more-45

2> Bert F..:

问题MVC在于人们认为视图,控制器和模型必须尽可能彼此独立.他们没有 - 视图和控制器经常交织在一起 - 将其视为M(VC).

控制器是用户界面的输入机制,通常在视图中被纠缠在一起,特别是对于GUI.然而,视图是输出,控制器是输入.视图通常可以在没有相应控制器的情况下工作,但是如果没有视图,控制器通常就没用了.用户友好的控制器使用视图以更有意义,更直观的方式解释用户的输入.这就是它使控制器概念与视图难以分离的原因.

可以将密封盒中检测区域的无线电控制机器人视为模型.

该模型完全是关于状态和状态转换,没有输出(显示)的概念或触发状态转换的内容.我可以获得机器人在场地上的位置,机器人知道如何转换位置(向前/向后/向左/向前迈出一步.很容易想象没有视图或控制器,但没有任何用处

想象一个没有控制器的视图,例如,在另一个房间的网络上的另一个房间中观看机器人位置的人,其中(x,y)坐标沿着滚动控制台向下流动.这个视图只显示模型的状态,但是这个人没有控制器.同样,在没有控制器的情况下很容易想象这个视图.

想象一下没有视图的控制器,例如有人被锁在壁橱里,无线电控制器调到机器人的频率.该控制器正在发送输入并导致状态转换,而不知道它们对模型做了什么(如果有的话).如果没有来自视图的某种反馈,很容易设想,但不是很有用.

大多数用户友好的UI使用控制器协调视图,以提供更直观的用户界面.例如,想象一个带触摸屏的视图/控制器,显示机器人在2-D中的当前位置,并允许用户触摸恰好位于机器人前方的屏幕上的点.控制器需要有关视图的详细信息,例如视口的位置和比例,以及相对于屏幕上机器人的像素位置触摸的点的像素位置)以正确解释这一点(与锁定在壁橱中的人不同)无线电控制器).

我已经回答了你的问题了吗?:-)

控制器是从用户获取输入的任何东西,用于使模型转换状态.尽量保持视图和控制器是分开的,但要意识到它们通常是相互依赖的,所以如果它们之间的边界模糊,即将视图和控制器作为单独的包可能不像你那样干净地分开就可以了.喜欢,但没关系.您可能必须接受控制器不会与视图完全分离,因为视图来自模型.

......是否应在控制器中进行任何验证?如果是这样,我如何将错误消息反馈回View - 如果再次通过Model,或者Controller是否应该直接将其发送回View?

如果在视图中完成验证,我应该在Controller中添加什么?

我说链接视图和控制器应该自由交互而不通过模型.控制器接受用户的输入并应进行验证(可能使用来自模型和/或视图的信息),但如果验证失败,控制器应该能够直接更新其相关视图(例如错误消息).

对此进行的酸测试是问自己一个独立的视图(即另一个房间中通过网络观察机器人位置的人)是否应该看到任何其他人的验证错误(例如衣柜里的人)试图告诉机器人离开现场).通常,答案是否定的 - 验证错误阻止了状态转换.如果没有状态tranistion(机器人没有移动),没有必要告诉其他意见.壁橱里的那个人没有得到任何反馈,他试图导致非法过渡(没有视图 - 糟糕的用户界面),没有人需要知道这一点.

如果那个带触摸屏的人试图将机器人送出现场,他会得到一条很好的用户友好消息,要求他不要通过将其发送到检测区域来杀死机器人,但同样,没有其他人需要知道这一点.

如果其他视图确实需要了解这些错误,那么您实际上是在说来自用户的输入和任何产生的错误都是模型的一部分,整个事情有点复杂......



3> JP Alioto..:

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

它指出 ...

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

换句话说,就是你的业务逻辑.控制器响应用户在视图中采取的动作并做出响应.您在此处进行验证,如果验证失败或成功,则选择适当的视图(错误页面,消息框,等等).

福勒还有另一篇好文章.



4> Dimitri C...:

MVC模式只是希望您将表示(=视图)与商务逻辑(=模型)分开.控制器部分只会引起混淆.



5> John Kugelma..:

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

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



6> BlairHippo..:

根据您的问题,我得到的印象是您对模型的角色有点模糊.模型固定在与应用程序相关的数据上; 如果应用程序有数据库,那么Model的工作就是与它通信.它还将处理与该数据相关的任何简单逻辑; 如果你有一条规则说明了所有情况下TABLE.foo =="万岁!" 和TABLE.bar =="Huzzah!" 然后设置TABLE.field ="W00t!",然后您希望模型处理它.

Controller应该处理大部分应用程序的行为.那么回答你的问题:

"我只需要调用Controller中的方法,就可以在视图中放置public void actionPerformed(ActionEvent e)吗?"

我会说不.我会说应该住在控制器中; View应该简单地将来自用户界面的数据提供给Controller,并让Controller决定应该响应哪些方法.

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

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

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

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

根据我的经验,模型和视图之间的直接通信应该非常非常有限,并且视图不应该直接改变模型的任何数据; 这应该是Controller的工作.

"如果在视图中完成验证,我应该在Controller中放置什么?"

往上看; 真正的验证应该在Controller中.希望你现在知道应该在Controller中放置什么.:-)

值得注意的是,它可以在边缘处变得有点模糊; 与大多数像软件工程一样复杂的东西一样,判断调用也会比比皆是.只需使用您的最佳判断,尝试在此应用程序中保持一致,并尝试将您学到的课程应用于下一个项目.



7> duffymo..:

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

服务层是了解用例,工作单元和模型对象的东西.对于每种类型的视图,控制器都是不同的 - 对于桌面,基于浏览器,Flex或移动UI,您将没有相同的控制器.所以我说它确实是UI的一部分.

面向服务:这就是工作的地方.

推荐阅读
帆侮听我悄悄说星星
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有