模型 - 视图 - 控制器(MVC)优于模型 - 视图的优点是什么?

问题描述:

任何人都可以举一个例子,说明为什么使用MVC而不是简单的模型和视图才是有利的。模型 - 视图 - 控制器(MVC)优于模型 - 视图的优点是什么?

注意:无论是MVC还是MVP(Model-View-Presenter),我都在谈论视图接收输入的地方,然后控制器会通过解释输入事件来响应输入事件,由模型完成。当模型改变时,视图将通过响应来自模型的事件来自我更新。

什么是不利的只是让模型对活动作出响应的视图,反之亦然?

在MVC中,如果我在那个影响控制器然后我就要做在控制器的变化的方式改变了模型。在模型视图中,如果我更改模型,我将不得不更新视图。

因此,看起来我们通过添加“控制器”部分来引入复杂性?

在MVC中,模型忽视它的环境,认为可能是太 - 假冒(盲目地)将其事件传递给控制器​​,控制器更了解视图和模型。所以当所有内容都说完之后,控制器就是系统中“不可重复使用”的一次性部分,因为它是最能感知上下文的组件。

,如果我改变了影响控制器的方式模型...

的模型应该暴露在这样​​简单的CRUD方法,那些使用方法不必一无所知关于传递的更新对象,以及模型内真正发生的事情。

这意味着视图,国际海事组织,通过产生传递记录做了一些工作,因为控制器应该是无状态的,认为是更持久。控制器被触发并且“踢入”用传递的对象完成他们的工作并且没有状态。

传递的数据是通过某种通用约定创建的。

让我走得更远。假设你有一个视图,一个tablegrid和一个控件,它的启用属性依赖于item在网格中被选中 - 你可以创建一个处理这些控件和内部逻辑的视图,这可能是要走的路在这样一个简化的例子中。

但是,你的观点越原子化,它们变得越可重用,所以你为每一个,每一个控制都创造了一个视图。现在,您正在查看视图必须了解彼此的情况,才能为正确的通知注册自己...

这是控制器的步骤,因为我们要将所有这些依赖关系粘贴到他身上,长期的一次性用品。所以控制器管理这种类型的视图通知方案。

现在你的观点是无知的,因为它们可以是独立的,因此可以重复使用。

您可以编写视图,而无需了解系统或“业务逻辑”,因为他们喜欢称之为。你可以编写一个模型,而不必知道你的目标太多(尽管它有助于调整模型,使其能够返回你想要的数据集)......但是控制器,它们是最后一个,你必须拥有之前的两个确定之前,你可以将东西连接在一起。

下面是另一个需要思考的问题 - 就像模型应该抽象并提供一个通用接口来管理它所管理的数据的底层实现一样(客户端不知道数据是否来自数据库,文件,程序设置等) - 视图还应抽象出它正在使用的控件。

因此,最终,这意味着一个视图不应(下面警告)具有的功能/性能看起来像这样:

public property BackgroundColor{get;set} 

也不

public function ScrollBy(x,y){} 

但是代替:

public SetProp(string name, object val){} 

And

public DoCmd(string name, object val){} 

这是有点人为的,记住我最终说过......你问为什么这是一个好主意?考虑到你可能总有一天想将某些东西从WinForms移植到Flex,或者简单地想使用一个新的控制库,而这个控件库可能不会暴露相同的功能。

我在这里说'端口',但这实际上不是目标,我们不关心移植这个特定的应用程序,而是让底层的MVC元素具有足够的通用性,足以传递到新的风格 - 在内部,离开一致且能力独立的外部接口完好无损。

如果你没有做到这一点,那么当你的新口味出现时,你在所有(可能可重用/可重构/可扩展)控制器中查看属性的硬引用必须被忽略。

这并不意味着这样的通用setter和cmds必须是所有视图能力的接口,而是他们应该处理'edge case'属性以及可以在传统中暴露的普通道具/ cmds硬连接的方式。把它想象成一个'扩展属性'处理程序。

这样,(再次设计),假设您正在构建一个框架,其中的按钮不再具有buttonIcon属性。这很酷,因为你有先见之明来创建一个按钮视图界面,​​其中buttonIcon是一个扩展属性,在视图中,当条件代码接收到set/get时,它现在不做任何操作。总之,我想说的是,MVC的编码目标应该是为模型和视图的通用接口赋予它们的底层组件,所以当你编写一个控制器时,你不必认真思考你是谁控制的。而且,虽然控制者正在(似乎是不公平地)成为重复使用的长期牺牲品 - 但这并不意味着所有的控制者都注定要死亡。因为他们的许多'思想'已经被推到了半智能的模型和视图以及其他控制器(例如:控制器对网格进行排序或操纵树视图) - 因此他们很小,他们希望很小,可以很容易地查看并且有资格在您的下一个项目中重新使用 - 或者克隆并调整为适合。 MVC/P的

+0

我给出一个简单的例子,说明为什么我没有看到优势。假设我们正在谈论一辆汽车。点击Car View的加速按钮,Controller通过调用Model.Accelerate()来响应,然后Model的速度发生变化,View响应Model事件并更新屏幕上的速度读数。现在,在模型视图(MV)按钮点击时,视图调用Model.Accelerate()和相同的情况发生没有涉及控制器。在MVC,如果我改变加速()为IncreaseSpeed()我将不得不更新控制器调用这种方法。在MV的情况下,我会做同样的更新,但视图。 – 2012-01-16 16:24:24

+0

继续以前的评论:因此,这些优点仅适用于以下情况:1.您的观点并不特定于您当前的项目(这很罕见)。我想不出任何! (可能缺乏经验)。 – 2012-01-16 16:31:45

+0

你有一个1对1的例子。该视图必须了解所有关于模型的EVERY WAY模型。这是所有依赖项的集合。而对于控制器来说,这个丛是分开的 - 每个事件都有一个单独的控制器 - 并且如果事件中的模型必须发生更奇特的事情,那么控制器中会发生变化(即控制器的潜在再利用的可能性会增加仅适用于一个事件)。用你的方式,每个增强/添加都会减少视图的可重用性。 – 2012-01-17 04:19:16

它实际上通过将工作流程逻辑与领域逻辑分离来降低复杂性。它还使编写单元测试更容易,并使应用程序更易于维护和扩展。

想象一下,如果您想添加新的数据类型。使用上述方法,您可能会复制新类中的许多工作流程逻辑,因为它可能会与域逻辑紧密耦合。

参与工作流逻辑分离到控制器的纪律使得它更有可能的是,你将有工作流程和逻辑域之间的依赖较少。添加新的数据类型将变得更加简单,您可以创建新的域对象并查看可以重复使用多少控制器,例如通过从控制器超类继承。

这也将使其更容易改变框架在未来的 - 模型可能不会有太大变化,因此会更加便于携带。

说了这么多,你可能要考虑MVVM取决于你使用的是什么作为您的表示层:Benefits of MVVM over MVC

优势(我说的是监督控制器这里)在MV包括:

  • 您可以处理复杂的数据控制器绑定代码,如果需要的话。

  • 您可以在没有UI测试框架的情况下测试复杂的表示逻辑。

  • 您还可以让图形设计师制作您的视图,而不是看到您的代码,并且在修正视图时不会弄乱您的代码。