我想我明白MVC的基本概念 - 模型包含应用程序的数据和行为,视图是负责它显示给用户,并与用户输入的控制器处理。 什么我不确定是在控制器正是去。
比方说,比如我有一个非常简单的应用程序(我专门在想Java的,但我想同样的原则适用于其他地方)。 我整理我的代码放入3包称为app.model
, app.view
和app.controller
。
内app.model
包,我有一个反映应用程序的实际行为几类。 这些extends Observable
并使用setChanged()
和notifyObservers()
来触发的观点适当的时候进行更新。
该app.view
包具有使用一个类(或多个类为不同类型的显示器) javax.swing
组件来处理的显示。 其中一些组件需要反馈到模型中。 如果我理解正确,视图不应该有任何与反馈 - 应该由控制器来处理。
那么,我是不是真的放在控制器? 难道我把public void actionPerformed(ActionEvent e)
在查看只需调用控制器中的方法? 如果是这样,应该任何验证等在控制器来完成? 如果是这样,我怎么回查看反馈错误信息 - 应该说经过再次型号,或应控制器只是把它直接回到看法?
如果验证在视图中完成的,什么我把控制器?
很抱歉的长期问题,我只是想记录我的认识过程,希望有人能澄清这个问题对我来说!
Answer 1:
在你建议的例子,你是对的:“用户点击‘删除此项目’按钮”,在界面基本上应该只是调用控制器的“删除”功能。 控制器,但是,不知道什么样的看法样子,所以你的观点必须收集一些信息,比如,“点击了哪个项目?”
在谈话的形式:
查看 :“嘿,控制器,用户只需告诉我,他希望第4项中删除。”
控制器 :“嗯,已经检查他的证件,他可以做到这一点...嘿,模型,我希望你能得到第4项,做任何你删除它。”
型号 :“项目4 ...明白了它删除,回到你身边,控制器。”
控制器 :“在这里,我将收集新的数据集回到你身边,看法。”
观点 :“酷,我现在会显示一组新的用户。”
在该节结束时,你有一个选择:要么认为可以做一个单独的请求,“给我最新的数据集”,因而是更纯粹,或控制器隐含返回新的数据与“删除设置“操作。
Answer 2:
这个问题MVC
是,人们认为视图,控制器,和模型都彼此尽可能的独立。 他们不-一个视图和控制器是相互联系的-认为它作为M(VC)
该控制器是用户界面,其通常在视图中挂住了,特别是与GUI的输入机构。 然而,视图是输出和控制器输入。 视图经常可以工作没有相应的控制器,但控制器通常远不如有用而不的图。 用户友好的控制器使用的观点来解释用户的输入以更有意义的,直观的方式。 这是什么使得它很难控制概念从视图中分离出来。
认为在密封箱作为模型上的检测领域的无线电控制的机器人。
该模型是关于没有输出(显示)的概念的状态和状态转换或什么触发的状态转换。 我可以在球场上机器人的位置和机器人知道如何过渡位置(走一步前进/后退/左/右。简单,不设窗户或控制器设想,但没有任何用处
认为一个视图的没有控制器,例如,在另一房间中观看机器人位置为(x,y)处的另一房间中的网络上的某人坐标流下来滚动控制台。 这种观点只显示该模型的状态,不过这家伙没有操控。 再次,易于设想没有控制器这一观点。
认为没有视图的控制器,例如有人锁定在与调谐到机器人的频率的无线控制装置的内室。 该控制器发送的输入并导致状态转换与不知道他们正在做模型什么(如果有的话)。 容易想象,但如果没有某种形式的从视图反馈不是真的有用。
最人性化的UI的坐标视图和控制器提供了更直观的用户界面。 例如,假设与显示机器人的当前位置的触摸屏中的2- d的视图/控制器和允许用户触摸到了恰好是在机器人的前屏幕上的点。 控制器需要的信息有关视图,例如,视口的位置和标度,以及光点的像素位置触摸相对于屏幕上的机器人的像素位置),以正确地解释这(与锁在柜子里用的人无线电控制器)。
有我回答你的问题了吗? :-)
该控制器是任何需要从用于使模型转变状态下的用户输入。 尽量保持视图和控制器分开,但要意识到他们往往相互依存,所以它是好的,如果它们之间的边界是模糊的,即具有视图和控制器作为独立的软件包可能并不如你会为分离干净喜欢,但是那是好的。 您可能需要接受控制器将无法完全从视图中分离出来作为视图是从模型。
......应任何验证等在控制器来完成? 如果是这样,我怎么回查看反馈错误信息 - 应该说经过再次型号,或应控制器只是把它直接回到看法?
如果验证在视图中完成的,什么我把控制器?
我说一个链接视图和控制器应不通过此模型自由交互。 控制器把用户的输入,并应(可能使用从模型和/或视图的信息)做验证,但如果验证失败,控制器应能更新其相关视图直接(如错误消息)。
造成这种情况的严峻考验是要问自己是一个独立的观点(即在另一个房间观看通过网络机器人位置的家伙)是否应该看到什么或不是别人的验证错误的结果(例如在衣柜里的家伙试图告诉机器人走下字段)。 一般来说,答案是否定的 - 验证错误阻止状态转变。 如果没有状态tranistion(机器人不动),也没有必要告诉其他意见。 在衣柜里的人只是没有得到,他试图使非法转移(无图 - 坏的用户界面)的任何反馈,并没有其他人需要知道。
如果与触摸屏的家伙试图发送机器人场上场下,他得到了一个很好的用户友好的消息,询问他不是通过发送它从检测场杀机器人,但同样,没有人需要知道这一点。
如果其他观点都需要了解这些错误,那么你实际上是说,从用户的输入,由此产生的误差是模型的一部分 ,整个事情是一个有点复杂...
Answer 3:
这里是一个很好的文章在MVC的基础知识。
它指出 ...
控制器 - 控制器转换的观点为行动相互作用由模型来执行。
换句话说,你的业务逻辑。 于由用户采取的行动中相应的视图,并响应该控制器响应。 你把这里的验证,如果验证失败或成功,选择适当的视图(错误页面,消息框,等等)。
还有一个很好的在福勒的文章 。
Answer 4:
MVC模式只是要你从业务逻辑 (=模型) 演示 (=视图) 分开 。 控制器部仅在那里引起混乱。
Answer 5:
根据你的问题,我开始觉得你是在模型的作用有点朦胧的印象。 模型被固定于与所述应用程序相关联的数据; 如果应用程序有一个数据库,模型的工作将是与它对话。 它也将处理与该数据相关联的任何简单的逻辑; 如果你有一个规则,即对于所有情况下TABLE.foo ==“万岁!” 和TABLE.bar == “好哇!” 然后设置TABLE.field =“W00t!”,那么你想要的模型照顾它。
该控制器是应该怎样处理了大部分的应用程序的行为。 因此,要回答你的问题:
“难道我把公共无效的actionPerformed(ActionEvent的五)在视图只有在控制方法的调用?”
我说没有。 我会说,应该在控制器中; 查看应该简单地养活从用户界面到控制器传来的数据,并让控制器决定哪些方法应该在响应被调用。
“如果是这样,应该任何验证等必须在控制器做了什么?”
您的验证大头真的应该由控制器来完成; 它应该回答的数据是否有效的问题,如果不是,喂相应的错误消息来查看。 在实践中,你可以结合一些简单的合理性检查纳入改善用户体验着想的视图层。 (我想主要的网络环境中,你可能希望有一个错误信息弹出,用户点击“提交”,而不是等待整个提交的时刻 - >程序 - >加载页面周期告诉他们之前,他们搞砸了。)只是要小心; 你不想重复劳动任何超过你必须这样做,在很多环境中(同样,我想在网络中),你经常要处理任何数据从用户界面来为污秽肮脏的包谎言直到你确定它实际上是合法的。
“如果是这样,我怎么回查看反馈错误信息 - 应该说经过再次型号,或应控制器只是把它直接回到看法?”
你应该有一些协议,建立在查看不一定知道接下来会发生什么,直到控制器告诉它。 屏幕是什么,你给他们的用户是敲敲罢了按钮后,? 该视图可能不知道,控制器可能不知道,直至其在它看起来只是得到的数据。 这可能是“回到这个屏幕等,如预期”或“留在这个屏幕上,并显示此错误消息”。
在我的经验中,模型和视图之间的直接沟通应该是非常非常有限的,并在视图不应直接更改任何型号的数据; 这应该是控制器的工作。
“如果验证在视图中完成的,什么我把控制器?”
往上看; 真正的验证应该是在控制器中。 希望你有一个什么样现在应该放在控制器的一些想法。 :-)
值得一提的,它都可以得到周围的边缘有点模糊; 与大多数事情一样复杂的软件工程,判断呼叫将比比皆是。 只需使用您的最佳判断,尝试这个程序中保持一致,并尝试应用你学习到下一个项目中的经验教训。
Answer 6:
实事求是地讲,我从来没有发现控制器概念是一个特别有用的。 我使用严格的模型/视图分离,我的代码,但没有明确定义的控制器。 这似乎是一个不必要的抽象。
就个人而言,完全成熟的MVC好像在工厂设计模式,很容易导致混乱和过于复杂的设计。 不要做架构宇航员 。
Answer 7:
控制器是真正的视图的一部分。 它的任务是找出哪些服务(多个)需要满足该请求,解组值从查看到该服务接口需要的对象,确定下一个视图,编组回响应成一种形式,下一视图可以使用。 它还处理那些抛出的异常,并将其呈现为视图,用户可以理解的。
服务层是知道的使用情况,工作单位,和模型对象的东西。 该控制器将是对每种类型不同的角度 - 你不会有台式机相同的控制器,基于浏览器的Flex或移动的用户界面。 所以我说这是真正的用户界面的一部分。
面向服务的体系:这就是工作完成。
Answer 8:
该控制器是主要用于视图和模型之间的协调。
不幸的是,它有时会最终被这样的观点混为一谈 - 小应用程序,虽然这不是太糟糕了。
我建议你把:
public void actionPerformed(ActionEvent e)
在控制器中。 那么在你看来你的行动听众应该委托给控制器。
作为验证的一部分,你可以把它放在视图或控制器,我个人认为它属于控制器。
我肯定会推荐考虑看看被动视图和监督演示(这基本上是什么模型视图演示被分成 - 至少福勒)。 看到:
http://www.martinfowler.com/eaaDev/PassiveScreen.html
http://www.martinfowler.com/eaaDev/SupervisingPresenter.html
Answer 9:
下面是我用一个经验法则:如果是我会专门用此页面上的操作过程,它所属的控制器,而不是模型。 该模型应该只提供一个连贯的抽象的数据存储。
我想出了这个与谁想到他们了解MVC,但真的没有开发人员编写的一大十岁上下的web应用程序的工作后。 他们的“控制器”被还原成八行调用静态类的方法被称为usuall无处: - /使他们的模型不是创建命名空间的方式多一点。 重构这个正确的做了三两件事:改变所有的SQL到数据访问层(又名模式),使控制器代码有点冗长,但很多更容易理解,并且降低了旧的“模型”文件不了了之。 :-)
Answer 10:
还注意到,每一次摆动小部件可以被视为包含三个MVC组件:每个人都有一个模型(即ButtonModel的),视图(BasicButtonUI)和控制(JButton的本身)。
Answer 11:
你基本上是看错你放什么在控制器中。 它是型号应与景观互动的唯一方式。 的actionPerformed可以放置在视图中,但实际功能,可以放置在另一个类将作为控制器。 如果你要做到这一点,我建议寻找到命令模式,这是抽象所有具有相同的接收器的命令的方式。 很抱歉的题外话。
总之,正确的MVC实现将有只以下交互:型号 - >查看 - >控制器控制器 - >查看
其中可能有另一种互动的唯一的地方是,如果你使用一个观察者更新视图,然后在视图将需要询问控制器所需的信息。
Answer 12:
据我所知,控制器从用户界面的操作到应用层的操作转换。 例如,在视频游戏控制器可能转化“感动这么多的像素鼠标”变成“希望在某某方向看,在一个CRUD应用,翻译可能是‘点击某某按钮’ “打印这件事”,但概念是相同的。
Answer 13:
我们这样做正是如此,使用控制器主要是为了处理和响应用户驱动的输入/操作(和_Logic的一切,除了视图,数据和明显_model东西):
(1)(反应,反应 - 什么web应用程序“确实”响应于用户)Blog_Controller
- >主()
- > handleSubmit_AddNewCustomer()
- > verifyUser_HasProperAuth()
(2)( “商业” 的逻辑,什么和怎样的webapp “认为”)Blog_Logic
- > sanityCheck_AddNewCustomer()
- > handleUsernameChange()
- > sendEmail_NotifyRequestedUpdate()
(3)(看法,门户网站,web应用程序是如何 “出现”)Blog_View
- > genWelcome()
- > genForm_AddNewBlogEntry()
- > genPage_DataEntryForm()
(4)(数据对象只,获取在_ 构建体(每个博客 *类中,用于一起保持所有的web应用/ inmemory数据作为一个对象的))Blog_Meta
(5)(基本数据层,读取/写入到DB中)Blog_Model
- > saveDataToMemcache()
- > saveDataToMongo()
- > saveDataToSql()
- > loadData()
有时我们会在哪里放的方法有点困惑,在C或L。但该模型是坚如磐石,晶莹剔透,因为所有在内存中的数据驻留在_Meta,这是一个没有脑子那里,太。 我们最大的飞跃就是采用_Meta使用,顺便说一下,因为这从各个_C,_L和_model对象清除了所有的污物,使这一切心理上易于管理,再加上,一举,它给了我们什么是所谓“依赖注入”,还是有办法的整个环境绕过所有数据(其好处是容易产生的“测试”环境)一起。
文章来源: What goes into the “Controller” in “MVC”?