作为一名认真的程序员,您如何回答MVC是什么问题? ,那么您可以自由地用不太可能引起争议的一般术语来描述它。
但是,如果您是在与知识渊博的听众(尤其是采访员)交谈时,我很难想到采取的方向不会冒“不正确!!”的反应的风险。我们都有不同的实际经验,而且我还没有真正真正遇到过相同的MVC实现模式两次。
那么,我该如何以正确,简洁和无争议的方式解释MVC?
#1 楼
MVC是一种软件体系结构-系统的结构-将域/应用程序/业务(无论您愿意使用什么)逻辑与其余用户界面分开。它通过将应用程序分为三个部分来实现:模型,视图和控制器。模型管理应用程序的基本行为和数据。它可以响应信息请求,响应指令以更改其信息状态,甚至可以在信息更改时通知事件驱动系统中的观察者。它可以是数据库,也可以是任何数量的数据结构或存储系统。简而言之,它是应用程序的数据和数据管理。
视图有效地提供了应用程序的用户界面元素。它将把来自模型的数据呈现为适合用户界面的形式。
控制器接收用户输入,并调用模型对象和视图以执行适当的操作。
总而言之,这三个组件共同创建了MVC的三个基本组件。
评论
+1我真的更喜欢将MVC看作是三个(或更多)模式的体系结构,而不是设计模式。没有规范的实现,它不是那么小,并且所有实现都比隐含的核心组件多得多。
– yannis
2011-12-30 8:43
尽管此答案有21票赞成票,但我发现“这可能是数据库或任何数量的数据结构或存储系统。(tl; dr:这是应用程序的数据和数据管理)”这句话太可怕了。该模型是纯业务/域逻辑。而且它可以而且应该不仅仅是应用程序的数据管理。我还区分了域逻辑和应用程序逻辑。控制器不应包含业务/域逻辑或直接与数据库对话。
–猎鹰
2011-12-31 13:58
我不能仅仅因为它声称mvc在表示层之外是合理的,所以就不同意这个答案。其余的答案都可以。 MVC应该在表示层开始和结束,并且绝对不应在其中包含业务逻辑和存储库。这样做可以有效地将整个应用程序放置在表示层中,并且不提供任何可用的API,而无需为原始应用程序设计这些API即可直接访问您的业务逻辑或纯数据。这不是为了扩展而开放的,视图模型使您更接近,但仍然缺少松散的耦合
–吉米·霍法(Jimmy Hoffa)
2012年10月21日18:46
@Jimmy:在MVC的许多构造中,模型可以在API中重用,因为它们不依赖于UI-视图和模型之间的分隔可解决这一问题。但这当然取决于您如何选择定义“模型”。如果要对MVC做出判断,则应首先说明您使用的是哪种MVC解释。
– Owen S.
2013年1月5日在22:13
@Yannis:这只是一个问题:什么是模式架构?您为什么不将其称为另一种设计模式? GoF(和Alexander)对设计模式的定义非常明确,很显然,模式不应该规定一种规范的实现(尽管两本书的普及都削弱了这一概念)。
– Owen S.
2013年1月5日在22:19
#2 楼
类比我这样向父亲解释了MVC:
MVC(模型,视图,控制器)是一种在应用程序中组织代码以提高可维护性的模式。
想象一个摄影师在工作室里用相机拍照。一个客户要他给盒子拍张照片。
盒子是模型,摄影师是控制器,摄像机是视图。
因为盒子会不了解相机或摄影师,它是完全独立的。这种分隔使摄影者可以绕着箱子走动,并以任何角度指向照相机以获取他想要的镜头/视图。
非MVC架构往往紧密地集成在一起。如果盒子,控制器和摄像机是一个相同的对象,那么每次我们想要获得新视图时,我们都必须拉开然后重新构建盒子和摄像机。另外,拍照总是像尝试自拍照一样-并不总是那么容易。在我觉得自己了解MVC的邮件列表问题/答案之后。 Quote:https://mail.python.org/pipermail/python-list/2006-January/394968.html
bwaha写道:
作者将wxPython中的mvctree.py称为MVC设计的一个例子。作者的建议。
MVC完全是关注点的分离。
模型负责管理程序的数据(包括私有数据和客户端)。数据)。视图/控制器负责为外界提供与程序的客户端数据进行交互的方法。
该模型提供了一个内部接口(API),以实现其他功能程序的一部分
,以便与之交互。视图/控制器提供了
外部接口(GUI / CLI / Web表单/高级IPC /等)以使程序中的所有内容都可以与之通信。
模型负责维护程序的完整性。
程序的数据,因为如果该数据损坏了,那么每个人的游戏就结束了。视图/控制器负责维护UI的完整性,确保所有文本视图都显示最新的值,禁用不适用于
的菜单项当前焦点等。
该模型不包含任何View / Controller代码。没有GUI窗口小部件类,没有用于布置对话框或接收用户输入的代码。
视图/控制器不包含模型代码;没有验证URL的代码或执行SQL查询的代码,也没有原始状态:
小部件所保存的任何数据仅用于显示目的,仅反映了存储在<模型。
现在,这是一个真实的MVC设计的测试:即使没有附加View / Controller,该程序在本质上也应具有完整的功能。
好的,外界以这种形式进行交互将很困难,但是只要知道适当的Model API规范,该程序就会像往常一样保存和操作数据。
为什么这可能吗?好吧,简单的答案是,这一切都要归功于
Model和View / Controller层之间的低耦合。
但是,这还不是全部。整个MVC模式的关键是这些连接的发展方向:ALL
指令从视图/控制器流向模型。模型
从不告诉视图/控制器该怎么做。
为什么?因为在MVC中,虽然允许视图/控制器对模型(特别是模型的API)了解得很少,但是不允许模型
了解关于视图/控制器的任何知识。
为什么?因为MVC旨在建立明确的关注点分离。
为什么?为防止程序复杂性失控,并使开发人员沉迷于其中。程序越大,
该程序中的组件数量越多。而且,这些组件之间存在更多的连接,对于开发人员而言,维护/扩展/替换单个组件的难度就更大,甚至
仅遵循整个系统的工作原理。问问自己:
查看程序结构图时,您是想看到树还是猫的摇篮? MVC模式通过不允许循环连接来避免后者:B可以连接到A,但是A不能
连接到B。在这种情况下,A是模型,而B是
View /控制器。
顺便说一句,如果您很敏锐,您会发现刚才描述的“单向”限制存在问题:模型如何通知/ Controller甚至不允许模型
知道View / Controller时,模型用户数据中的更改,不必介意向其发送消息吗?但请放心:有一个解决方案,即使开始时似乎有点round回,它也很整洁。稍后我们将返回到这一点。
实际上,然后,一个View / Controller对象可以通过
模型的API,1.告诉模型做事(执行命令),然后2.
告诉模型给它做事(返回数据)。 View / Controller
层
将指令推送到Model层,并从Model层提取信息。
这是您的第一个MyCoolListControl示例出错的地方,
因为该类的API要求将信息压入其中,所以您又回到了各层之间的双向耦合,
违反了MVC规则并将您直接丢回猫的脑袋。 />[大概]首先要避免的摇篮体系结构。
相反,MyCoolListControl类应该与流程一起使用,从
中获取所需的数据。需要时在下面的图层。对于列表窗口小部件,通常意味着先询问其中有多少值,然后依次询问每个项目,因为这是最简单,最松散的方法从而使耦合最小化。而且,如果该小部件希望以良好的字母顺序
向用户提供这些值,那么
就具有吸引力。当然,还有它的责任。
现在,正如我之前暗示的那样,最后一个难题是:在基于MVC的情况下,如何使UI的显示与模型的状态保持同步
/>系统?
这是问题所在:许多View对象都是有状态的,例如复选框
可能被打勾或未打勾,文本字段可能包含一些可编辑的
文本。但是,MVC规定所有用户数据都存储在Model
层中,因此,由其他层保留的用于显示目的的任何数据(
复选框的状态,文本字段的当前文本)因此必须为
该主要Model数据的辅助副本。但是,如果模型的状态发生变化,视图的状态副本将不再准确,并且需要刷新。
但是如何? MVC模式可防止模型将该信息的新副本推入View层。哎呀,它甚至不允许
模型向View发送消息以表明其状态已更改。
差不多。好的,不允许Model层直接与
其他层进行通信,因为这样做会要求它对那些层有所了解,而MVC规则可以防止这种情况。但是,如果一棵树落在
森林中而没人在周围听到它,它会发出声音吗?
您所看到的答案是建立一个通知系统,为Model层提供一个可以向所有人宣布的地方,特别是
它刚刚做了一些有趣的事情。然后,其他层可以
在该通知系统中发布监听器,以监听他们实际上感兴趣的那些公告。Model层
不需要了解谁在监听(或即使任何人
都在听!);它只是发布公告,然后就忘记了
。而且,如果有人听到了该公告并且感觉像是在做之后的事情-例如向模型询问一些新数据,以便它可以更新其屏幕显示-那就太好了。该模型仅列出
它作为API定义的一部分发送的通知;而
其他人用这些知识做什么取决于他们。
MVC被保留,每个人都很高兴。您的应用程序框架
可能会提供一个内置的通知系统,或者如果没有,您可以编写自己的通知系统(请参阅“观察者模式”)。
...
无论如何,希望能有所帮助。一旦了解了MVC的动机之后,事情就以它们的理解方式开始变得有意义了,即使乍一看它们似乎比必需的更为复杂。 br />
干杯,
拥有
评论
MVVM和MVCS怎么样,我从softwareengineering.stackexchange.com/questions/184396/听到了您的MVC答复。
– dengApro
17/12/27在11:39
#3 楼
MVC通常是一个流行词。它以前被认为是一种模式,但其1979年的原始定义已被愚蠢地删除,传递,误解,脱离原始上下文。它的定义一直很模糊,以至于它开始类似于一种宗教,虽然这无疑有助于其货运信奉者捍卫它,但其名称已不再与一套可靠的准则相关联。因此,它不再真正被视为一种模式。
MVC从来都不是用来描述Web应用程序的。
没有现代操作系统,也没有语言。
(其中一些人实际上是1979年定义的多余)
是做的。
我们现在处理的是一个淫秽的Web-MVC混合广告,它的流行语状态恶劣,定义不清,并且以半文盲的编程人员作为目标人群,因此宣传效果非常差到一般的软件模式。
因此,MVC成为了那些不想真正考虑太多的人的关注点分离。
数据模型是以一种方式处理,
以另一种方式处理,
其余的仅被命名为“控制器”,并由读者自行决定。
90年代的网站/网络应用
它们是混杂的意大利细面条代码的可怕组成部分。
UI更改,重新设计和数据重排非常困难,昂贵,耗时,令人沮丧,命运。 />诸如ASP,JSP和PHP之类的Web技术使得将视图关注点与数据以及应用程序关注点混合在一起非常容易。进入该领域的新手通常会发出与旧时代一样不可分割的代码泥潭。
因此,越来越多的人开始在支持论坛上无休止的循环中重复“使用MVC”。人数增加到包括经理和营销人员的程度(从某种意义上说,在gui编程的那个时代,这个词就已经很熟悉了,在这种情况下该模式才有意义),这成为了我们现在必须面对的流行语的庞然大物。
这是常识,而不是方法论。
,这是起点,不是解决方案。
这就像告诉人们呼吸空气或进行仰卧起坐,不是治愈癌症。
评论
当然这并不是流行语。的确,MVC比其他设计模式更普遍并且不那么独特,因此您可以将其视为组织原则或范例。但是无论您怎么说,它都是许多非常成功的面向对象框架中的基本概念。假装这只是一个时髦的词,即一个时髦的短语,意义不大,这是对OP的损害。
–卡莱布
2011年12月30日下午6:28
对于那些确实不需要的概念来说,这是个花哨的词。哪种设计模式/架构不符合该描述?
– yannis
2011-12-30 12:30
+1坦率地说,一旦掌握了基础知识(内聚性,耦合性,可读性,正统性等)并将其与现代语言的功能相结合,这些东西中的大多数就显而易见。
–lorean
2011-12-30 19:24
数据模型以一种方式处理,视图以另一种方式处理,其余的仅被命名为“ controller” +1
–c69
2012年5月2日19:02
-1。我希望所有愚蠢的+1评论能得到-10。考虑到耦合和内聚的基本原理,这种“显而易见的”情况如何? UI架构比比皆是,包括MVC,MVP,MVVM,Forms和Smalltalk的模型。一些公司还将WS-CAF中的Composite Application体系结构推向了极致。说“常识”会自动将您带到MVC,这与笛卡尔所谓的上帝证明一样多。显然,这是您所知道的,但是您的答案表明您对其他方法的无知或无法扩大自己的视野。
– Aaronaught
2012年10月21日在16:35
#4 楼
定义它的最好方法是查阅曾发明它的Trygve Reenskaug的原始著作:http://heim.ifi.uio.no/~trygver/themes/mvc/mvc-index.html尤其是,本文通常被视为定义文本:http://heim.ifi.uio.no/~trygver/1979/mvc-2/1979-12-MVC.pdf
模型
模型代表知识。模型可以是单个对象(而不是有趣的对象),也可以是对象的某种结构...
模型与其部分之间应该一对一的对应另一方面,以及模型所有者所感知的表示世界。因此,模型的节点应该代表问题的可识别部分。 (例如,日历约会)以及实施细节(例如,段落)。
视图
视图是其模型的(视觉)表示。通常,它将突出显示模型的某些属性,而抑制其他属性。因此,它充当表示过滤器。
视图被附加到其模型(或模型部分),并通过提问从模型中获取表示所需的数据。它还可以通过发送适当的消息来更新模型。所有这些问题和消息都必须使用模型的术语,因此视图必须知道其代表的模型的属性的语义。 (例如,它可能会要求提供模型的标识符并期望使用Text的实例,但可能不会假定该模型属于Text类。)控制器是用户与系统之间的链接。它通过安排相关视图以在屏幕上的适当位置显示自己,从而为用户提供输入。它通过向用户显示菜单或其他提供命令和数据的方式来提供用户输出方式。控制器接收到这样的用户输出,将其转换为适当的消息,然后将这些消息传递给一个或多个视图。
控制器永远不要补充视图,例如,它永远不要连接视图。相反,视图永远不应该了解用户输入,例如鼠标操作和击键。应该总是有可能在控制器中编写一种方法,该方法将消息发送到视图,这些视图精确地重现任何用户命令序列。
编辑器
控制器连接到其所有视图,它们被称为控制器的组成部分。一些视图提供了一个特殊的控制器,即编辑器,它允许用户修改视图所呈现的信息。这样的编辑器可以被拼接到控制器及其视图之间的路径中,并将充当控制器的扩展。编辑过程完成后,将编辑器从路径中删除并丢弃。 。控制器将通过询问视图来获得编辑器的权限-没有其他合适的来源。
#5 楼
MVC是一种用于将业务逻辑与表示分离的设计模式。它与许多其他设计模式不同,因为它通常不是简洁地实现,而是框架的基础。
虽然实现战略模式的应用程序只是其中的一小部分细节,但是说Web应用程序使用MVC设计模式非常明确其体系结构。
评论
这不是严格有用的,实现MVC模式有非常具体的要求,使其不同于MVP,MP,MVVM。它的目标受众也不同于其他演示模式。
–伊恩
2011-12-30 12:43
#6 楼
MVC是一种软件设计,用于分隔系统或子系统的以下组件:模型-有关应用程序或其组件的状态的数据。可能包括用于修改或访问的例程。视图-数据(模型)的解释。这仅限于视觉表示,但可以是音频,派生信息(例如,将统计信息传递到另一个模型对象)等。此外,单个模型可能具有多个视图。
控制-处理外部输入到系统,调用模型上的修改。控件/视图可能紧密相关(在UI的情况下)。但是,可以处理完全独立于视图的其他外部输入(例如网络命令)。
#7 楼
我会说MVC是一个概念或一系列类似的模式。我认为这篇文章值得阅读。 Martin Fowler的GUI架构
评论
Fowler的文章非常出色,每个使用MVC术语的人都应该阅读。我发现特别有趣的两点是,GUI中术语MVC的最初用法与Web框架中的用法有很大不同,并且在GUI中,发现视图和控制器之间的分隔没有预期的有用。
–汤姆·安德森(Tom Anderson)
2012年10月21日在22:38
#8 楼
首先,您必须确定问题的提出者是谁,以及他正在寻找什么样的答案。您用另一个问题来回答这个问题,例如“从什么意义上说?”。您可以询问他们是否一般来说是指MVC,MVC的特定实现(即asp.net MVC,spring MVC,smalltalk MVC等),从技术上讲,它是什么?是哲学上的(是的,它也有哲学上的意思),等等。
如果这是测试中的问题,并且您不能要求问询者澄清,那么您将不得不猜测
一个很好的简单答案是:
MVC是一种软件用户界面体系结构,用于分离结构和行为方面的内容,以便于更易于维护的软件。
您还可以说:
通过将View与Controller从Model分离,它鼓励隔离基于组件的组件。他们的责任。从理论上(通常在实践中),这可以通过防止系统的不同部分混合并创建更复杂的系统来帮助提高可维护性。
但是,最后,将根据您是否提供他们期望的答案来判断您。解决该问题的唯一方法是找出他们期望的答案。
#9 楼
这就是我要说的。我会尝试用移动应用程序来解释它,因为它是我最熟悉的,并且因为我认为在开始制作移动应用程序之前我并不完全理解它。 />表示层,即可以(应该,通常是)完全在xml中指定用户界面。为了简单起见,假设一个xml文件描述了应用程序中的一个屏幕。 XML文件指定控件,控件的布局,位置,颜色,大小,字符串标签...有关表示的所有内容。但是,对于何时调用它,何时将其放置在屏幕上一无所知。它是独立布局还是更大布局的一部分?您已经拥有了:完美的VIEW。现在,显然需要在某个时候将视图放置在屏幕上,那么该怎么办呢?您的控制器在Android中称为“活动”。顾名思义,活动就是一些活动。即使其唯一目的是显示在步骤1中定义的视图,它也将执行某些操作。因此,活动获取一个视图并将其显示在屏幕上。由于视图对活动一无所知,因此,活动对实际表示一无所知。我们(程序员)可以多次重新排列视图的布局,而无需在活动中甚至只更改一行代码。 xml布局,而无需实际执行任何操作。假设我们要存储用户输入的数据。活动需要解决这个过程,从用户获取数据到将数据传递给其他人来处理(处理,存储,删除)。它会传递给谁?好,到一个模型。我喜欢将模型视为纯粹的.java类,对其所处的应用程序上下文一无所知。(实际上,情况绝不会如此)。
假设我有一个Person类,它具有三个属性:名称,地址,年龄。我的XML定义的布局具有3个字段供用户输入:名称,地址,年龄。我的活动从用户输入中获取三个值,创建一个新的Person对象,并在其上调用一些方法,该方法知道如何处理某些Person特定的逻辑。
您已经有了它。模型视图控制器。
评论
注意:如果您使用的是ASP.NET,则MVC具有第二个含义,即:ASP.NET MVCMVC在这里很好地解释了codepeaker.com/blogs/…