Win32 MVC模式实现

4
我目前正在开发一个Win32应用程序,考虑采用MVC模式。根据该模式,处理用户交互的代码应该位于控制器中,以便可以相应地更新模型和/或视图。 但在Win32中,这是否意味着我的windowProc应该位于控制器中?这对我来说似乎有点奇怪,我会创建一个窗口和所有UI内容,然后在控制器中子类化wndProc。 另一方面,如果我不这样做,我最终需要在视图中使用控制器实例来处理模型。我很确定这不是正确的方式。 如果有人能指导我正确的方向,那就太好了! 谢谢。
3个回答

3

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


1
MSDN上说:“控制器。控制器解释用户的鼠标和键盘输入,根据需要通知模型和/或视图进行更改。” 我理解的是,控制器响应Windows消息,然后调用适当的UI方法来更新它,但我可能没有抓住重点。 至少我猜测控制器是GUI和数据之间的链接。 - dotminic
1
MVC模式并没有严格的定义。我总是说 - 在设计模式之前要先动动脑筋。用户界面对用户输入做出反应,并生成诸如“按下Go按钮”或“在文本框中输入短语”等事件传递给控制器。 - Karel Petranek
我同意这个观点!但我的问题是,我如何通知控制器?由于视图中没有控制器的实例,所以我应该实现类似于Qt信号的东西吗?就像我在下面告诉dajames的那样,我想走“艰难的路”一次,这样我就知道在使用框架进行此类实现时发生了什么。 - dotminic
2
许多MVC实现基本上将控制器视为输入源,将视图视为纯输出。因此,您可以根据模型的状态更新视图,然后控制器接收用户输入并使用它来修改模型。在这种设计中,窗口过程完全适合于控制器。这也似乎是一种更清晰的设计,因为视图和控制器都有更狭窄的责任范围。 - jalf

1

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

在SDI Doc / View应用程序中,Windows GUI的事件驱动性质使得将一些控制器功能放入视图变得非常诱人 - MFC中的大量向导生成的代码都这样做。

在MDI应用程序中,每个模型有多个视图,让其中任意一个充当控制器显然是错误的,因此诱惑是将控制器逻辑放入文档类或框架窗口中...但是将一个新类添加为控制器并使用它来包装域逻辑并将该类连接到MFC有点困难,大多数人似乎不会麻烦去做。最简单的方法是将文档视为合并了模型和控制器。

这是针对MFC的(尽管它有许多缺点),但仍然是编写仅限于Windows GUI应用程序最高效的框架之一。如果您不喜欢MFC,或者需要一个可以支持多个平台的框架,您可能已经拥有更好的MVC支持 - 例如,请参见此文章中关于在Qt中支持MVC。


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

0

问题可能在于你的抽象层次。

假设你有相同的数据模型和修改控件,而你想要将整个界面从win32更改为HTML。那么整个界面部分就是视图。

现在你甚至可能有多个模型和控制器,比如用于域数据和当前应用程序视图的控制器。

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


这就是我想做的,但是我如何使用win32获得那种抽象层次?我知道我需要尽可能地解耦视图,以便我可以更改为任何类型的视图,但这就是我遇到的问题。我似乎找不到一种清晰的方法来解耦我的视图和控制器类。 - dotminic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接