模型视图控制器

时间:2009-01-24 00:41:40

标签: language-agnostic design-patterns oop

我的GUI中有一个树控件(自然有很多GUI /平台特定的功能来处理节点) 我有一个数据模型,它有自己复杂的节点集,子节点,属性等。
我希望树显示模型的表示,能够将消息发送到模型内的节点,并被告知在模型更改时重绘自己。

但我不希望GUI代码需要知道模型数据类型的细节,我不想通过将模型链接到GUI类来污染模型。

我无法理解控制器应该如何执行此操作以及应该提供哪些功能?

(这是用C ++编写的,但这不重要)

6 个答案:

答案 0 :(得分:2)

GUI“控件”并不完全适合模型 - 视图 - 控制器模式,因为它们通常具有自己的内部模型,而不是接受对它的引用。如果控件是以这种方式构造的,那么您将需要一个适配器类,它将控件的内部模型“数据绑定”到底层数据模型。

这可以实现类似于模型 - 视图 - 控制器的功能,除了适配器类扮演视图连接组件(从数据模型更新GUI)和控制器(将GUI事件解释为模型操作)的角色)。

答案 1 :(得分:1)

Qt为model-view programming提供了一组课程。例如,您可以将树视图挂钩到文件系统模型,并且两者都不能直接了解彼此的任何信息(除了在视图中指向模型的指针)。

答案 2 :(得分:1)

您的要求是:

  • 树显示模型的表示
  • 树中的节点可以向模型
  • 中的节点发送消息
  • 树根据模型更改重绘自身

我不知道你在这里使用的是什么类型的数据,但是分层模型是一件相当简单的事情。我将把它作为给定的知识如何迭代分层数据并填充树视图。

您的控制器应具有用于向模型发送消息的成员函数。参数应该是模型元素和要发送的消息。这样,UI完全不知道消息如何到达元素,但可以通过消息获取消息。

最后一个要求更棘手,并且取决于一些事情(例如,控制器的生命周期,应用程序架构等)。我将假设控制器只要树视图生存。如果是这种情况,那么您的控制器应该提供一种方法来设置模型更改的回调。然后,当控制器更改模型时,它可以在不知道UI的情况下回调到UI。

答案 3 :(得分:1)

我认为你的麻烦始于不幸的选择。 '控制'的东西与MVC中的'控制器'没有任何关系。这就是为什么有些GUI库使用其他名称(小部件是常见的)。

你的“树控件”是视图,而不是控制器。它应该与GUI相关联,既可以用于显示,也可以用于获取GUI事件并将其转换为“树事件”。

控制器获取那些“树事件”并对模型进行必要的修改。这就是你将'行动'与'回应'联系在一起的地方。

答案 4 :(得分:1)

第一个解决方案:您可以在模型和视图之间实现“主题观察者”模式,模型作为主题,视图作为观察者。每当模型状态发生变化时,它都可以向所有注册的观察者发射事件,他们可以自行更新。

第二个解决方案:引入一个控制器,它以模型作为观察者注册。从Model接收更新事件后,它可以更新视图。即使您可以使用控制器和视图之间的另一个主题观察者模式来分离控制器的视图

第三个解决方案:使用MVP模式。模型视图演示者。只要控制器中没有太多计算,就使用该模式,即控制器的工作只是更新其相应的视图。控制器成为Presenter。

答案 5 :(得分:0)

你需要一个位于显示小部件之外但具有树状态的控制器(在MFc中有CTreeView / CTreeCtrl类 - 在Qt中有类似的分离)树控制器处理所有数据存储并调用重绘树小部件。
树窗口小部件中的更改将发送到树控制器 - 因此该控制器需要了解gui函数。

模型将需要用于节点的所有相关参数的set / get函数。但是这些可以返回简单类型,因此不依赖于gui。

更新模型的视图需要发送消息,如果你不希望模型知道你的gui消息,你可以做的最好的事情是从树控制器注册一个回调函数(一个函数的void指针) - 并调用此方法进行更新。 然后,此更新函数可以在模型中查询更改。