试图了解MVC。这是正确的吗?

时间:2012-09-06 21:42:00

标签: c# model-view-controller events design-patterns chess

解释的方式是通过使用事件和发布/订阅模型。基本上,模型只是数据而且它不了解视图/ GUI / UI。该模型通常只是一个抽象对象,可以对其数据进行操作,并可以执行操作等等。

视图是一个不同的类,它响应模型中的更改并通常将此数据显示给用户。以前,我不知道如果没有视图和模型之间的耦合可能会发生这种情况,但是如果用事件解释事件就会清除这种混乱。这是否意味着该模型包含在发生有趣事情时本身会引发的公共事件?例如,如果我们正在编写一个国际象棋游戏,当一个棋子移动时,该模型会将PieceMoved的事件与必要的信息(哪个棋子从哪里移动到哪里等)和视图一起提升可以订阅这样的事件,然后显示从旧广场移动到新广场的动画片。

仍然让我困惑的部分是控制器的确切性质。我无法理解它如何提供模型和查看新信息。我想控制器包含对模型和视图的引用。保持国际象棋的例子,控制器只会响应用户输入(例如移动一块),然后只是建议模型想要移动到哪里?然后模型获取此信息,查看它是否是合法移动,如果是,则相应地更新模型,引发视图响应的PieceMoved事件并相应地更新图形领域?

最后,控制器如何找出试图移动的部分?看起来这种类型的东西与视图密切相关(假设首先单击要移动的部分,然后是目标方块)。我想控制器会响应鼠标点击并将这些坐标发送到模型,但模型如何知道如何翻译这些坐标以找到被选中的部分?这与观点密切相关吗?看起来该视图必须执行一些逻辑处理,而不是简单地响应模型和控制器,但它不再是一个正确的视图(而是视图/模型混合)。

4 个答案:

答案 0 :(得分:0)

MVC是一个非常通用的概念。它实施的方式有很多种,其中大多数都有各种妥协。

我看到的问题是你试图采用一个深奥的概念并将具体的实现细节应用于它。这很难做到,除非你有一个非常具体的实现(asp.net MVC,fubuMVC,spring MVC,smalltalk MVC,等等),每个人都以不同的方式完成通知和事件处理等事情。

如果您只是在谈论MVC概念,那么您必须以通用方式处理MVC概念。我知道如果你有一个具体的实现可能会更容易理解,但是你会根据对实现的理解走向理解模式(MVC)的道路,这可能会扭曲你对模式本身的理解。

因此,当您阅读有关消息或事件时,您必须只考虑“某些实现定义的机制”。它可能是一个回调,或者它可能是一个C#事件,或者它可能是一个Windows消息,或者它可能正在使用该力;)

编辑:

关于您的更新,我会重复。您无法回答有关通用概念的实现特定详细信息。您必须为某人定义一个特定的实现,以便能够告诉您如何完成这些实现细节。

答案 1 :(得分:0)

这个问题有很多答案,主要是因为有很多不同的MVC框架。有些例子,请查看http://martinfowler.com/eaaDev/uiArchs.html。我也可以提供一个MVVM视角,因为这是我最近一直在做的工作,所以这就是我的想法。

Model层基本上是您的数据和业务逻辑。您可能正在与数据库或Web服务进行通信。如果你最终编写了一个系统,那不仅仅是一个GUI,这是你的可重用代码。

ViewModel然后位于模型的顶部,并且基本上将数据呈现为(ahem)属性。它使用INotifyPropertyChanged接口在数据发生变化时告诉UI。如果您有数据用于在将其推送到模型层之前构建某些内容,那么它就存在于此处。您通常会将您可以在UI中执行的操作公开为ICommnands。

View层是耦合最少的,因为它只使用绑定来连接到ViewModel。可视化的东西是与用于改变其形式的可选IValueConverters绑定的属性,例如

Visibilty="{Binding IsVisible, Converter={StaticResource booleanToVisibiltyConverter}}"

Action UI元素绑定到ViewModel上的Commands以启动ViewModel操作。

Command="{Binding DoSomething}"

答案 2 :(得分:0)

关于MVC模式的坏处是:

  • 每个人都有她/他自己的版本
  • 首先要抓住它有点抽象

好事:

  • 实际上非常简单
  • 这是划分大多数应用程序的绝佳方式

回答你的问题:

模型

这很简单。模型应该只知道自己。它是和游戏规则。如果您可以在桌面应用程序或Web桌面应用程序中重复使用它,那么您就知道正在构建模型。

视图

这也不复杂。它是视觉部分,也是处理用户输入的部分。理解视图在MVC模式中的作用的最重要的概念是它们必须提供一种方法来调用系统的puclic接口。在国际象棋游戏中,它是必须绘制元素并检测用户使用鼠标/键盘做什么的游戏。当用户做某事时,视图负责调用系统:例如。 “User1想要将片段从X移动到Y”(重要:大多数时候你不希望视图触发像User1点击坐标x,y那样的调用。像素是视图的领域。系统必须接收与图形表示方式无关的订单。

控制器

你是对的,这个并不是那么直截了当。控制器是必须处理对系统的公共接口的调用的控制器。在您的示例中,它将接收一个调用'User1从X移动到Y'并调用模型的适当对象中的方法(在这种情况下很可能是 board )。因此,控制器完全知道模型中的对象。但是,它也可以包含应用程序中必需的代码,但不属于模型的域。您必须检查用户是否有权访问系统?你必须将该调用记录到文件中?好吧,大多数时候这种事情会进入控制器。

然而,这只是我自己的MVC版本(我和其他人一样,也有我自己的......)。

答案 3 :(得分:-1)

因此,如果您有一个视图(国际象棋棋盘)和国际象棋棋盘的控制器,控制器将为其提供事件。当你移动一块时它会引发PieceMoved事件,该事件应该将信息传递给这个事件,例如当前位置和所需位置。

对于一个非常简单的应用程序,您可能无法掌握模型的概念。可能有一个可以在多个视图(例如细节和创建视图)上重用的计费模型。您不希望每次需要时都复制此代码,因此在您的控制器中,每个事件都会触及需要它的计费模型。通过创建模型,您可以封装代码。