MVC: 为什么我们需要“控制器”,或者说我们在什么情况下应该使用这种模式?

14

我已经阅读了许多有关MVC的出版物,但我仍然无法清楚地理解为什么我们需要“控制器”。

我通常在客户端-服务器模型中编写应用程序:

服务器包含所有业务逻辑,并且对GUI一无所知。它完成主要工作,尽可能具有可移植性。

客户端是一个GUI,它绑定到服务器,与用户交互,将用户的命令发送到服务器

我喜欢这种架构,但我想不通为什么人们真正需要另一个媒介在客户端服务器之间,这似乎就是控制器

更新:简单的例子:假设我们需要编写一些数据记录器。数据来自COM端口,使用某种协议进行编码。需要在一个简单的日志窗口中显示接收到的消息。

我会这样做:

服务器包含以下项目:

  • Data_receiver:实际上从COM端口接收原始数据,但它是接口,因此我们能够创建另一个从任何其他源接收数据的类;
  • Data_decoder:获取原始数据并返回结果解码消息,它也是接口,因此我们可以轻松更改编码协议;
  • Data_core:使用Data_receiverData_decoder实例发出信号给客户端。

客户端包含以下项目:

  • 应用程序核心:创建Data_receiver实例(连接到COM端口的实例),Data_decoderData_core(它接受Data_receiverData_decoder实例的引用),还创建GUI简单日志窗口(它接受Data_core的引用);
  • GUI简单日志窗口:绑定到Data_core,即侦听由其发出的信号,并显示接收的数据。

根据我对MVC的理解,GUI不应该直接从 Data_core 接收到信息,因为这应该由controller负责并将数据传递给GUI。但是,如果GUI直接从model中获取这些数据,会发生什么糟糕的事情呢?


3
我喜欢这个问题,因为没有人给出“你做错了”的答案。这意味着整个社区要么不知道这个问题的答案(不太可能),要么是MVC和MVVM被过度强调到像你这样的个人认为它们是必需的,而事实上,有时它们会妨碍代码的可读性。 - cwharris
2
此外,像MVVM和MVC这样的模式只是“模式”。这意味着当您编写SOLID代码时,它们会出现在您的代码中。换句话说,如果您正在编写SOLID代码,而这些模式没有出现,那么您可能正在编写不需要这些模式的代码。 - cwharris
此外,在您的示例中,您的客户端和服务器都具有控制器代码。例如:文本字段仅是文本字段。应用于该文本字段的验证逻辑是控制器代码。如果您发现自己不断重复该验证逻辑,则可能以DRY方式编写代码,这不需要一个真正的“控制器”类。另一方面,如果您有两个视图都对其文本字段执行相同操作(将它们转换为整数,确保它们在1-100之间),则可以考虑对textfield进行子类化并添加控制器逻辑。 - cwharris
MVC与你的产品是否为客户端-服务器模式无关。 - Neil McGuigan
@DmitryFrank,如果你不熟悉SOLID设计,请务必查看一下。这将帮助你更好地理解如何分析这样的场景,并应用适合的模式。http://en.wikipedia.org/wiki/SOLID_(object-oriented_design) - cwharris
显示剩余2条评论
4个回答

2
过去,我曾多次问过自己同样的问题,最近我在阅读JSP模型2架构方面的内容,维基百科上提到了以下内容。
“J2EE平台Web层技术文献经常使用“Model 1”和“Model 2”这两个术语,但没有解释。这个术语源于JSP规范的早期草案,描述了JSP页面的两种基本用法模式。虽然这些术语已经从规范文档中消失了,但它们仍然被广泛使用。Model 1和Model 2只是指控制器Servlet的存在或不存在(分别)来调度客户端层的请求并选择视图。”
这基本上意味着MVC模式本身有变化,因此您可以根据项目始终应用MVC或MV模式。但是,正确的MVC架构确实应该有一个控制器,因为模型和视图不应直接相互交流。

1
“客户端-服务器”与MVC没有任何关系,据我所知。
我的理解是:
模型是您构建数据的方式。
视图是可见表示形式(GUI)。
控制器使用逻辑来控制视图和/或其他逻辑。
背后的想法是将可视化表示与逻辑分离。因此,当您抓取视图时,不会复制逻辑。... 所以在您的情况下,您可能仅在客户端使用MVC,并且需要一个控制器,因为所有魔术都发生在这里。

但逻辑和可视化表示已经被客户端-服务器架构分割开来了:服务器拥有数据和逻辑,客户端代表数据。我更新了我的问题(添加了一个简单的应用示例),请以某种方式对其进行评论(其中应该是模型,哪些是视图,以及哪些是控制器)。 - Dmitry Frank
我猜 Data_core 是你的控制器。你创建的 window 是视图。当你有多个窗口并且有不同的事情发生时,MVC架构就会启动,因为你的 Data_core 会变得非常复杂。所以你会尝试创建一些小的控制器岛屿,它们只处理其对应视图的逻辑。然后你会将所有控制器连接到 Data_core - nooitaf

1

在阅读您的客户端-服务器模式细节时,我想到了MVVM模式。当您希望执行单元测试时,最好将VM(ViewModel)视为控制器。

按照您的模式,经典的客户端/服务器模式中,控制器、模型和视图位于您称之为Data_receiver、Data_decoder和Data_core的服务器代码中。在您的“客户端”中,您再次拥有控制器和视图。

从服务器代码中分离出一个控制器,用于接收和解码来自COM的信号和数据,一个模型,控制器将数据传递给它,并在路由到和从数据库返回数据时接收数据,以及一个视图,用于对模型中的原始数据进行编码和格式化,这是非常有用的。

遵循不要重复自己(DRY)原则,您可能会注意到在代码的服务器和客户端部分中都有控制器代码,其中您重复了代码或职责。

当您以测试驱动开发方式推动开发时,将其分成不同的部分非常有用,这样您可以附加各种测试。


-1
“迟做总比不做好”,我想纠正你对“为什么需要在客户端和服务器之间再加一层”的误解。
如果你阅读以下内容,答案就非常明显了,MVC是三角形的架构模型。
视图向模型请求,模型向控制器请求,控制器处理并发送回视图。
The Model is the way you structure your data.
The View is the visible representation. (GUI)
The Controller uses the logic to control the view and/or other logic.

Regards, Pavan.G


谢谢你的回答,但我已经阅读了“三角形模型”等相关内容。对于我来说,为什么它如此优秀以至于有这么多人谈论它还是不太清楚。如果您能编写我在问题中提到的简单日志记录应用程序的MVC方式,我将不胜感激。 - Dmitry Frank

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接