繁体   English   中英

试图了解MVC。 这是正确的吗? [关闭]

[英]Trying to understand MVC. Is this right? [closed]

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

视图是不同的类,可响应模型中的更改,通常将这些数据显示给用户。 以前,我不知道在没有视图和模型之间耦合的情况下如何发生这种情况,但是用事件解释它会消除很多混乱。 这是否意味着该模型包含公共事件,当发生有趣的事情时,公共事件本身就会引发? 例如,如果我们正在编程一个国际象棋游戏,那么当一个棋子被移动时,该模型将使用必要的信息(该棋子从何处移动到何处等)引发PieceMoved事件,并且视图可以订阅该信息。一个事件,然后显示从原来的方块移动到新方块的动画。

仍然令我困惑的部分是控制器的确切性质。 我在理解它如何为模型和视图提供新信息时遇到麻烦。 我想象控制器包含对模型和视图的引用。 与Chess示例保持一致,控制器会只是响应用户输入(例如,移动一块),然后向模型建议将哪个块想要移动到哪里? 然后,模型将获取此信息,查看它是否合法移动,如果是,则相应地更新模型,引发PieceMoved事件,视图对此作出反应并相应地更新图形领域?

最后,控制器如何找出要移动的零件? 似乎这种类型的事物与视图紧密相关(例如,移动涉及先单击要移动的物体,然后单击目标方块)。 我想控制器将响应鼠标单击并将那些坐标发送到模型,但是模型如何知道如何转换这些坐标以找到选定的那一部分? 这与视图是否紧密相关? 似乎视图必须执行一些逻辑处理,而不是简单地响应模型和控制器,但是那样就不再是合适的视图(而是视图/模型混合)。

MVC是一个非常通用的概念。 有很多不同的实施方式,其中大多数都有某种折衷。

我看到的问题是,您正在尝试采用一个深奥的概念并将具体的实现细节应用于该概念。 除非您有一个非常具体的实现(asp.net MVC,fubuMVC,spring MVC,smalltalk MVC等),并且每个人都以不同的方式完成诸如通知和事件处理之类的工作,否则这很难做到。

如果您只是在谈论MVC概念,则必须以通用方式处理MVC概念。 我知道,如果您有一个具体的实现,可能会更容易理解,但是随后您会基于对实现的理解而走上对模式(MVC)的理解,这可能会使您对模式本身的理解有所偏差。

因此,当您阅读有关消息或事件的信息时,只需考虑“某种实现定义的机制”。 它可能是回调,也可能是C#事件,或者可能是Windows消息,或者可能正在使用force;)

编辑:

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

这个问题有很多答案,主要是因为有太多不同的MVC框架。 有关一些示例,请访问http://martinfowler.com/eaaDev/uiArchs.html 我也可以给出MVVM的观点,主要是因为这是我最近一直在努力的方向,所以这就是我的想法。

模型层基本上就是您的数据和您的业务逻辑。 您可能在此处与数据库或Web服务进行交谈。 如果最终编写的系统不只是一个GUI,那么这就是您的可重用代码。

然后,ViewModel位于模型的顶部,并且基本上将数据作为属性呈现(显示)。 它使用INotifyPropertyChanged接口告知UI数据何时更改。 如果您拥有在将数据推送到模型层之前用于构建数据的数据,则该数据将保存在此处。 通常,您将以ICommnands的形式公开可以在UI中执行的操作。

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

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

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

Command="{Binding DoSomething}"

关于MVC模式的坏事是:

  • 每个人都有自己的版本
  • 首先要掌握一点抽象

好东西:

  • 其实很简单
  • 这是拆分大多数应用程序的绝佳方法

但是要回答您的问题:

该模型

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

风景

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

控制器

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

但是,那只是我自己的MVC版本(我和其他所有人一样,也有我自己的版本... :)

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

对于非常简单的应用程序,您可能不了解模型的概念。 一个可能具有可以在多个视图(例如明细和创建视图)上重用的计费模型。 您不想每次都需要重复此代码,因此在控制器中,每个事件都将到达需要它的计费模型。 通过创建模型,您可以封装代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM