【问题标题】:Win32 MVC pattern implementationWin32 MVC 模式实现
【发布时间】:2010-10-27 16:46:30
【问题描述】:

我目前正在开发一个 win32 应用程序,我想我应该使用 MVC 模式。现在根据模式,处理用户交互的代码应该在控制器中,以便我可以相应地更新模型和/或视图。 但是在 Win32 中,这是否意味着我的 windowProc 应该在控制器中?这对我来说似乎有点奇怪,我会创建一个窗口和所有 UI 的东西,然后在控制器中子类化 wndProc。 另一方面,如果我不这样做,我最终将需要视图中的控制器实例,以便我可以处理模型。我很确定这不是要走的路。

如果有人能指出我正确的方向,那就太好了!

谢谢。

【问题讨论】:

    标签: c++ model-view-controller design-patterns winapi


    【解决方案1】:

    处理用户交互的代码是视图。控制器将模型与视图“粘合”起来(简单地说)。窗口过程肯定属于 GUI,即视图部分。通过这个 GUI,您将生成控制器将捕获、调用模型并响应它们的事件。

    【讨论】:

    • msdn 说:“控制器。控制器解释用户的鼠标和键盘输入,通知模型和/或视图进行适当的更改。”我对此的看法是,控制器响应 Windows 消息,然后在 UI 上调用适当的方法来更新它,但我可能错过了重点。好吧,至少我想我知道控制器是 GUI 和数据之间的链接。
    • MVC 模式并没有真正严格定义。我总是说 - 在设计模式之前使用你的大脑。 UI 对用户输入做出反应,并向控制器生成诸如“按下 Go 按钮”或“输入的文本字段中的短语”之类的事件。
    • 我同意这一点!但是我的问题是,我如何通知控制器?由于我在视图中没有控制器实例,我应该实现类似 Qt 信号的东西吗?正如我在下面告诉 dajames 的那样,我想以“艰难的方式”做一次,所以我知道如果我使用框架来实现这种实现,我会知道幕后发生了什么。
    • 很多MVC实现基本上都是把控制器当作输入源,把视图当作纯输出。因此,您根据模型的状态更新视图,然后控制器接收来自用户的输入并使用它来修改模型。采用这种设计,窗口过程完全适合控制器。这似乎也是一个更简洁的设计,因为视图和控制器都获得了更狭窄的职责范围。
    【解决方案2】:

    MFC 的文档/视图模型是对 MVC 的半生不熟的尝试。如果您正在考虑使用 MFC,那么您可以使用 CView 派生类来表示视图(呵呵!)和 CDocument 派生类来表示模型。不幸的是,MFC 并没有真正尝试将控制器功能与模型或视图分开。

    在 SDI Doc/View 应用程序中,Windows GUI 的事件驱动特性使得将一些控制器功能放入视图中变得非常容易——而 MFC 中的大部分向导生成的代码都是这样做的。

    在 MDI 应用程序中,每个模型有多个视图,显然将它们中的任何一个作为控制器都是错误的,因此很容易将控制器逻辑放入文档类或框架窗口中……但它添加一个新类作为控制器并使用它来包装域逻辑并不难。不过,将该类引入 MFC 有点困难,而且大多数人似乎并不在意。最简单的方法是将 Document 视为模型和控制器合二为一。

    MFC(尽管有许多缺点)仍然是用 C++ 编写仅限 Windows 的 GUI 应用程序最高效的框架之一。如果您不关心 MFC,或者如果您需要一个可以支持多个平台的框架,那么您可能已经有了更好的 MVC 支持——例如,请参阅 this article 在 Qt 中支持 MVC。

    【讨论】:

    • 我没有使用 MFC,我自己编写了所有的 Win32 代码,所以这确实是一个问题,即在哪里以及如何处理用户交互代码。在视图中拥有控制器的实例听起来很糟糕,在控制器中处理消息似乎也不是要走的路。
    • 在 MVC 中,控制器是知道应用程序逻辑的代码块;它知道应该如何绘制视图来表示模型,以及用户与视图的交互应该如何更新模型。当你点击一个窗口时,视图类应该得到点击消息并调用控制器。控制器永远不应该知道消息是什么——视图应该将其抽象掉。 Windows 使纯 MVC 变得困难,因为控件(它们是视图逻辑的一部分)通常包含数据(应该属于模型)。
    • 我真的建议使用一些框架(无论是 MFC、Qt 或 wxWidgets 还是其他),因为这需要大量的工作来开发 Windows GUI 应用程序,并且还有助于思考了解这些概念,而不会陷入实现细节。在 Win32 级别上工作只会让生活变得比需要的更难。
    • 在这种情况下,这意味着我需要在视图内有一个指向控制器的指针,对吗?我知道我会更好地使用 Qt 或其他东西,但我想“手工”完成,至少这一次可以很好地理解它是如何运作的。
    • 本质上是的。一种方法:应用程序拥有控制器类的一个实例。控制器具有创建文档和视图类实例的方法,并将对自身的引用(或指针)作为参数传递给它们的构造函数。 Paul Dilascia 有一本非常古老的(MFC 之前的)书叫做 Windows++,它讨论了围绕 win API 构建一个简单的框架。如果您仍然可以找到副本,值得一看以了解基础知识。
    【解决方案3】:

    问题可能在于您的抽象级别。

    假设您有相同的数据模型,以及如何修改它的控件,并且您想将整个界面从 win32 更改为 HTML。整个界面位就是视图。

    现在您甚至可以拥有多个模型和控制器,例如域数据以及当前查看应用程序的方式。

    控制器通常需要存在于视图特定部分的生命周期之外。

    【讨论】:

    • 这就是我想要做的,但我怎样才能使用 win32 获得那种级别的抽象?我知道我需要尽可能多地解耦视图,以便可以更改为任何类型的视图,但这就是我遇到的麻烦。我似乎找不到一种干净的方法来解耦我的视图和控制器类。
    猜你喜欢
    • 2016-09-30
    • 1970-01-01
    • 2014-01-23
    • 2015-02-12
    • 2012-08-22
    • 1970-01-01
    • 2010-12-12
    • 2011-11-30
    • 1970-01-01
    相关资源
    最近更新 更多