在MVC上,几个视图可以具有相同的控制器,还是一个视图必须具有一个唯一的控制器?


15

在围绕MVC设计项目的体系结构时遇到一些问题。(这是一个C ++ / Marmalade SDK项目,我没有使用任何特定的MVC框架,而是创建了一个。)

在几篇文章中(例如在史蒂夫·伯贝克Steve Burbek的原始文章中),我一直在阅读“ MVC triad”的概念,这使我感到困惑,因为我从字面上理解了这个概念。当我第一次阅读它时,看起来应用程序是围绕“ MVC triad”单元构建的(我应该为每个UI单元构建一个单元),但是我发现这相当不灵活,我认为这并不是打算使用MVC的方式。然后,进一步研究该问题,我发现了控制器和视图紧密耦合的几个示例,即一对一关系-TextEditView具有TextEditController。

但是,当我回到项目时,发现使用一个控制器(按“逻辑单元”,如AddElementController)和该特定控制器的多个视图可能会很有用。

我显然在考虑类似AddElementController之类的东西,它应该具有某种选项卡式UI。我是否应该具有一个具有AddElementTabView的AddElementController以及用于选项卡的几个AddImageView,AddSoundView等?还是每个选项卡视图都应该有一个不同的“子控制器”?

总而言之,关于MVC模式(不是X框架对此模式的特殊理解/实现),为一个控制器拥有多个视图是否正确,还是每个视图都应具有其特定的控制器?

另外,在控制器上保留一些状态信息是否正确还是应该是无状态的(意味着状态应该放在某些非域状态模型上)?

在此先感谢所有。

Answers:


14

问题在于,MVC模式是在不再存在的系统中设计的。当UI库不存在时,它是在Smalltalk中发明的。要进行窗口对话,请画出所有框,突出显示适当的正方形,确保所绘制的文本最终出现在正确的位置...等等...

想象一下,只用一块大画布编写对话框应用程序会是什么样子。这就是MVC来自的世界。

该系统中的“视图”是一个文本框,它是负责绘制框,文本,绘制选定区域,响应文本更改等的类。

“控制器”是另一类,负责接收在此框中发生的鼠标事件,例如鼠标移动,按下键,按下键,单击等,它可以决定发生了什么。我们应该更改文本吗?我们应该改变选择吗?像那样的东西。

“模型”是代表类的基本数据和状态的另一个类。文本框模型将具有文本,字体,选择等。

如您所见,在这种情况下,这三个组成部分非常纠缠于一个想法的表示。在这种情况下,说“三合会”是有意义的。

今天,如果您正在创建UI库并使用原始绘图命令,则可能会执行类似的操作。但是“ MVC”模式的应用已经超出了其最初的目的。现在,您拥有的“视图”实际上可能是一个完整的对话框,并且控制器正在响应“ textChanged”或“ buttonClicked”之类的事件。当今的MVC中的模型通常与系统完全脱节(但通常通过提供某种观察者接口链接到视图),并且可能有许多视图与一个模型相关联。

例如,在我最近设计的系统中,我们有大约10多个视图,所有视图都观察到一个文档“持有者”及其活动文档。主绘图界面与文档的布局,观察所选项目并提供记录界面的各种属性视图以及显示整个文档而不是仅可见窗口的较小比例的主视图进行交互。这些视图中的某些视图具有复杂程度各异的控制器,这些控制器将GUI事件转变为对文档的更改,从而可以通知其各种视图。

您还能将这种关系称为“三合会”吗?也许可以,但是我认为这暗示了MVC以前较旧的应用程序太多了。

您可以共享具有不同视图的控制器吗?取决于视图的相似程度。我发现一般来说,这种类型的对象具有特定于其所控制的视图的行为以及它所操纵的模型是非常可重用的...但是总是有例外。


5

这取决于。MVC有多种变体,有些只有1:1关系才有意义(例如“不起眼的对话框”),而有些则不是。我建议阅读“ 构建自己的CAB ”系列文章,解释最重要的MVC变体。


3

视图在MVC中没有控制器。Controller是负责人,因此Controller决定要呈现的View,并且View不在/不在乎哪个Controller请求了View。

您可以/将绝对有一个控制器中的多个视图。如果您想坚持使用MVC模式,只需考虑为每个视图创建一个模型。


3

控制器的目的是控制用户与您的域模型的交互-也就是说,它是用户所见(视图)与应用程序状态(模型)之间的间接级别。

当用户发出请求时,该请求将定向到控制器。控制器通常通过某种服务类来决定如何将请求转发给应用程序。然后,它解释来自该服务类的响应,并决定将哪个视图发送回用户。

如果用户只能对控制器发出一种请求,则控制器可能总是返回相同的视图(1:1),并且它总是需要相同的响应。例如,HelloWorldController将始终返回HelloWorldView显示“ Hello,World!”。

另一方面,控制器通常必须根据模型的说明决定不同的视图。将TeamRosterController可能会返回一个RugbyTeamRosterView或一FootbalTeamRosterView,根据要求团队的类型。

控制器通常最好是无状态的,尽管可能需要或希望对用户会话的状态进行某些访问。如果可能,您应该分别管理对该状态的访问。

我强烈建议您查看实际的MVC框架,以了解其功能和工作原理。您不必使用它,但是在构建自己的工具之前,您一定会获得更好的了解。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.