控制器应了解视图和模型吗?或相反亦然?


13

我在概念上试图了解我是否应该这样做:

item = Model()
screen = View()
brain = Controller(item, screen)

或这个..

brain = Controller()
item = Model(brain)
screen = View(brain)

或这个..

class Controller():
    def __init__(self):
        item = Model(self)
        screen = View(self)

还是完全其他的东西?

Answers:


18

对我来说,第一种选择是有意义的。Controller的工作是在视图和模型之间进行协调。从这一角度来看,使控制器成为控制对视图和模型的引用的控制器是有意义的。

没有一个模型和一个视图就不能真正拥有一个控制器,但是仅仅拥有一个视图或只有一个模型(例如,在单元测试中)会更加有意义。这就是为什么要将这些依赖项传递给Controller而不是其他两个的原因。


9

ModelView相互独立的。

不要将MVC Controller作为MVC结构的大脑。你可以把它作为调度员负责处理来自浏览器的请求,并分派他们到Model。然后,它采用的数据来自Model并将其打包在一个模板友好的方式,然后将其发送到View

Model大脑在MVC结构,这是你应该把你的业务规则。业务规则在多个控制器之间是通用的。因此,文档控制器和报表控制器都可以使用用户模型来查看谁有权访问那些东西。您不想在两个控制器中都重复这些规则。

View应使用的HTML模板非特定数据源的方式来呈现数据。它不应与数据库的模式紧密绑定。要显示文档的标题,您将使视图输出名为的模板变量的内容document_title,只有Controller知道如何设置该变量,并且只有Model知道为什么文档具有该标题。


1
我喜欢您的回答,因为它与我对MVC的整体理解相融合。但是,它没有解决问题的重要部分,特别是三合会的哪些部分持有对其他部分的引用?我认为混淆来自您所描述的事实,即视图是“带有孔的哑模板”(即,不引用Controller,但是Controller知道View并将模型中的数据插入到其中)。同时,我经常看到的另一件事是,视图应将用户操作发送到控制器。视图如何在没有引用C的情况下做到这一点?
alnafie

@alnafie您已经将MVC框架简化为仅3个类。环顾现有的MVC开源框架,您将发现有更多的条件才能使之工作。必须有更高的东西来管理框架的所有部分。称为控制器的事物,以及处理路由到视图中动作的事物的事物。
Reactgular

3

最初定义MVC是为了简化桌面应用程序的编程。该视图订阅了模型事件,并在模型更改时更新了表示。控制器仅将用户界面事件(例如,按下按钮)转换为对模型的调用。因此,控制器和视图取决于模型,但彼此独立。该模型独立于两者。这允许多个视图和控制器在同一模型上工作。

用于Web 1.0应用程序的“ MVC”体系结构(全页刷新,无AJAX)有所不同。Web请求被调度到控制器。控制器以某种方式修改模型状态,然后发送一个或多个模型以通过视图呈现。控制器和视图都取决于模型,但是控制器也取决于视图。

对于Web 2.0应用程序,我们将在客户端返回经典的MVC体系结构。模型,视图和控制器都作为Javascript对象驻留在客户端。控制器将用户事件转换为模型动作。模型动作可能会也可能不会导致向服务器发出AJAX请求。同样,该视图订阅模型事件并相应地更新演示。


+1好答案。我可以理解经典意义上的桌面应用程序的模型回调。让我想起了Microsoft的旧MFC。
Reactgular

2

该视图应订阅模型中的更改。订阅的丰富性很宽泛,因为它们可能是详细的(向我显示此特定项目的库存更改)或通用的(模型已更改);视图可以响应于更改通知来查询模型。该视图在屏幕上显示其所需的模型元素集,并在处理更改通知时更新屏幕。

控制器应根据用户指示(例如,放置键盘,鼠标和菜单命令)将更改推送到模型。

该模型维护模型和订阅列表,并应通过订阅来通知适用的更改视图。

还需要一种机制来创建新的视图和控制器(因为在MVC中,您应该能够具有相同模型的两个或多个视图(它们可以是相同的视图(点)或不同的视图(点)))。从逻辑上讲,我们可以认为控制器需要执行或可以访问视图和控制器(对)工厂,该工厂可以是控制器或其他组件的一部分。


-1 Models不通知ViewsControllers查询Model更改,然后渲染Views以呈现这些更改。
Reactgular

4
在MVC中,如果@MathewFoscarini,则视图会订阅来自模型的更改。参见例如wiki.squeak.org/squeak/598

我认为我们不是在谈论现有MVC框架的差异。Zend MVC,C#.NET和CakePHP不会将模型连接到视图。这些框架中的视图是独立的。我不知道您使用过哪种MVC,但我称其为非传统MVC。
Reactgular

6
@MathewFoscarini:这些都是Web框架,尽管它们称自己为“ MVC”,但它们并没有遵循经典的MVC体系结构。
凯文·克莱恩

2
我不确定任何MVC都比Smalltalk MVC更“传统”,因为它是第一个描述模式的地方。

1

MVC更像是一种模块化模式。其目的是,每当要更改用户界面布局(视图)时,都不必更改应用程序逻辑(控制器)或内部数据处理(模型)。

为了实现这一点,该模式是隔离每个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.