为什么要使用MVC模式?


74

如今,每个使用Web应用程序的人似乎都希望对所有内容使用MVC。但是,我很难说服自己使用这种模式。我了解一般的想法是将代表程序的后端逻辑与前端逻辑分开。通常,视图在一定程度上似乎总是依赖于控制器,最终取决于模型。我看不出添加控制器能给我带来什么好处。我已经读过很多关于“这是应用程序应该被设计的方式”的大肆宣传,但是也许我仍然不明白应该去哪里。每当我与其他人谈论MVC时,似乎每个人对于什么属于什么类别都有不同的想法。

那么,为什么要使用MVC?通过将MVC仅仅从前端逻辑和后端逻辑中分离出来,我可以获得什么?(我看到的这种模式的大多数“优势”都是通过将接口与实现分开来获得的,而无法解释拥有单独的“控制器”的目的)


9
MVC只是关注分离的实现。任何实现都可以。不使用关注点分离往往会导致大泥球
Raynos

1
@Raynos:也许吧。但这不是“炒作”的根源。
Billy ONeal

3
炒作遵循炒作曲线。不要让它对您影响太大。从我的角度来看,MVC是用于SoC的可靠体系结构,易于实现。我想不出一个可靠的选择。
雷诺斯2011年

大多数现有的用户界面框架都将V和C紧密地链接在一起,当您切换到另一个框架时,您将需要重写视图和控制器(从M到用户所看到的界面)
棘手的怪癖

但是,关注点分离是面向对象开发的一个属性。您不必使用MVW模式来实施正确的关注点分离代码吗?
Bastien Vandamme 2014年

Answers:


50

嘿。Martin Fowler同意您对MVC的困惑:

我认为将MVC视为一种模式并不是非常有用,因为它包含许多不同的想法。在不同地方阅读有关MVC的不同人士会从中获得不同的想法,并将其描述为“ MVC”。如果这没有引起足够的混乱,那么您会得到对MVC的误解,这种误解是通过中国低语系统发展而来的。

但是,他继续对推动MVC的原因给出了更为明确的解释之一:

MVC的核心是我所说的“独立演示”。分离演示的背后思想是在建模我们对现实世界的感知的领域对象与作为屏幕上看到的GUI元素的演示对象之间进行清晰的划分。域对象应该完全独立并且可以在不引用演示文稿的情况下工作,它们还应该能够支持多个演示文稿,并且可能同时支持。

您可以在此处阅读Fowler的全文。


19

我觉得这很大程度上取决于您要解决的问题。我看到分离如下:

模型 -我们如何表示数据?例如,如何从对象到持久性存储(例如DB)->如何将“用户”对象保存到数据库?

控制器 -我在做什么?这是正在发生的动作,需要在概念上执行。例如,为用户开具发票需要经历什么阶段?注意,这可能会影响任何数量的对象,但是对它们如何持久保存到数据库一无所知。

视图 -如何渲染结果?

我觉得您看到的问题是,许多Web应用程序都是数据库的CRUD(创建-检索-更新-删除)接口。即,告诉控制器“添加用户”,然后仅告诉模型“添加用户”。一无所获。

但是,在您执行的操作未直接应用于模型更改的项目中,控制器使工作变得更轻松,系统更易于维护。


1
“在您执行的操作不会直接应用于模型更改的项目中”“模型”在这里是什么意思?数据库?因为我与之交谈的每个人都说这样的动作仍然属于模型而不是控制器。(例如,控制器仅应处理HTTP内容...)
Billy ONeal

什么算作HTTP内容?我将在控制器中包括以下内容:解组HTTP请求参数,检查参数的基本状况,确定需要执行的操作,访问适当的模型对象(读取,写入或两者),根据模型的响应产生最终结果,将其传递给视图。一个用于控制器的愚蠢示例可能是生成随机数的Web服务-在这种情况下,没有“模型”可供研究(至少在我看来……)
Unk

这些都是模型问题。甚至“决定需要做什么”(“前端控制器”)也是一个模型。
Billy ONeal

2
更不用说控制器对于不将模型硬耦合到视图非常有用。以及允许您通过一个控制器将许多视图连接到许多模型。
雷诺斯2011年

1
@Billy:如果允许视图与模型“混淆”(除了查询模型的值),那么最终得到的视图更像是控制器。我认为MVC的Model-GUI-Mediator化身更多。控制器在模型(域的行为和数据)和GUI(模型的屏幕表示)之间进行中介。该视图仅将交互传递给控制器​​(用户单击...)。控制器决定需要在模型上调用什么(如果有的话)。好处:...
Marjan Venema

8

你不应该

我再改一下。您应该使用将逻辑与视图分开的体系结构。如果需要,如果需要的逻辑不一定适合模型(例如,遍历URL块的树遍历),则应使用利用控制器的体系结构(例如MVC)。

来自CI和Yii,我认为拥有专用的控制器是一个很酷的主意。但是,当使用适当的RESTful接口开发应用程序时,似乎不需要控制器来处理非特定于模型的逻辑。因此,当我转向Django,然后转向Pyramid(两者都不完全遵循MVC架构)时,我发现控制器实际上并不是我正在构建的应用程序所必需的组件。请注意,这两个框架均具有“控制器式”功能,例如Pyramid中的URL Dispatching,但这是配置项,而不是运行时项(例如Yii中的CController)。

归根结底,真正重要的是将视图与逻辑分离。这不仅可以清理实施方面的内容,还可以使FE / BE工程师并行工作(在团队环境中工作)。

(旁注:我不是专业地开发Web应用程序,因此可能缺少某些内容)


我完全同意,很好的答案。控制器并非总是必需的,它只是作为视图与模型进行通信的策略。
猎鹰

@Falcon:看,那是我的困惑。我已经看到不止一个人说视图完全不应该与控制器对话。只能与模特对话...
Billy ONeal

1
如果您使用的是实际的MVC实现,则视图不会与控制器(或与此相关的模型)对话。控制器设置模型的状态,为视图准备数据,并将其推送到视图。
Demian Brecht

@Demian:我听说过相反的情况(控制器实际上应该什么也不做)。经常。这是我使用这种模式的最大问题;似乎没人同意这是什么。
Billy ONeal

3
是的,我经常听到,如果一个房间里有10个程序员,您将获得9种关于MVC的不同定义。确实,重点是关注点分离。发生的其他事情似乎是一场宗教辩论。
Demian Brecht

1

是的,关于此的术语是一团糟。很难谈论,因为您永远不会完全理解术语中的含义

至于为什么要使用单独的控制器,其原因可能取决于您所讨论的控制器版本。

您可能需要一个控制器,因为在运行测试时,视图中有一堆您没有编写且可能不想测试的小部件。是的,您将实现与继承分开了,因此您可以使用存根或模拟程序来测试其他内容,但是当您测试具体视图本身时,就很难了。如果您的控制器没有运行相同代码的任何小部件,那么您可以直接对其进行测试,也许不需要通过脚本来测试这些小部件。

恕我直言,其他版本很难显示出具体的好处。我认为这主要是关注点分离问题-将纯可视化GUI关注点与适用于GUI的逻辑分离,但不属于业务模型(诸如将模型中的更新转换为应显示小部件的事情)。但是在实践中,这两个类之间可能紧密耦合(即使它们通过接口进行通信),以至于很难将它们合并成一个视图而过度烦恼,并且要留意功能可能更可重用的方式如果他们分裂了。


0

简而言之:关注点分离。除了谈论“正确的”工作方式,编写更简洁的代码等外,您还可以说MVC使您可以更轻松地重用代码。基本上,您可以对模型和控制器进行编程,而无需费力即可在Web应用程序,桌面应用程序,服务中的任何地方模糊地使用它们。


2
这与仅定义UI层和功能层没有什么不同。您尚未说明为什么需要控制器位。
Billy ONeal

-3

在行业设置中很好地说明了使用MVC结构的基本原因,在该行业设置中,使用单个工作流程,单个模型来开发任何应用程序。因此,如果项目从组织的一个模块转移到另一个模块,则可以更轻松地更好地了解工作场景。它结合了工作的清晰度。
虽然您(作为个人)对您的应用程序会采用不同的方法,但是当您与合伙人一起工作时,您将首先讨论并着重考虑两家(您和您的合伙人)共同同意的模型。在这种情况下,它以明显的优势将分别分配给您和您的同事的职责分开。


-3

我认为MVC只是管理人员的理论家的时髦词汇。但是,话虽如此,当前具有HTML5流行的响应式设计的Web迭代,并试图创建可以在Web和iPhone上运行的单行数据库编程,这很适合MVC的一般思想。Web前端技术实际上正在借助Jquery(CSS控件的新迭代)以光速发展,而服务器端的事物则以蜗牛的速度发展。

最终,服务器上的所有内容实际上将仅仅是将数据泵送到前端的服务或“小程序”,并且根据您所拥有的客户端的类型,这些数据将被不同地使用和显示。从这个意义上说,MVC是有意义的。

在这方面,我相信在当前的现实世界中,MVVM确实是比控制器更好的“模式”或您想要调用的任何东西,因为控制器总是必须返回模型来更改视图,而且这很慢。在MVVM模式中,ViewModel可以立即更新视图。此外,MVVM模型还促进了RESTful设计原则恕我直言。


这仅仅是您的意见,还是可以通过某种方式进行备份?
蚊蚋

3
(并没有投票)好吧,如果是这样的话,它已经流行了40多年了。
比利·奥尼尔

2
我鼓励您对MVC模式的起源及其产生的其他模式(例如MVP和MVVM)进行一些额外的研究。模式的历史要比当前的流行语更令人相信。

1
来自模型视图控制器历史记录:“ MVC显然是由Trygve Reenskaug于70年代在Xerox Parc发明的。我相信它的首次公开露面是在Smalltalk-80中。很长一段时间以来,几乎没有关于MVC的公开信息,即使在Smalltalk中-80文档,在MVC上发表的第一篇重要论文是Glenn Krasner和Stephen Pope撰写的“在Smalltalk -80中使用模型-视图-控制器用户界面范式的食谱”,于1988年8月/ 9月发行在JournalOfObjectOrientedProgramming上(JOOP)。”

有很多更重要的流行词,例如KISS,已经存在了很长时间,并且得到了很多关注。
Michael Barber
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.