Language agnostic 模型视图控制器

Language agnostic 模型视图控制器,language-agnostic,design-patterns,oop,Language Agnostic,Design Patterns,Oop,我的GUI中有一个树控件(自然有很多GUI/平台特定的功能来处理节点)。 我有一个数据模型,它有自己复杂的一组节点、子节点、属性等。 我希望树显示模型的表示,能够向模型内的节点发送消息,并在模型更改时被告知重新绘制自身 但是我不希望GUI代码需要知道模型数据类型的细节,也不希望通过将模型链接到GUI类来污染模型 我不知道控制器应该怎么做,它应该提供什么功能 (这是C++但不重要)qt提供一组类。例如,您可以将树视图挂接到文件系统模型上,并且两个视图都不直接了解彼此(视图中指向模型的指针除外)。您

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

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

我不知道控制器应该怎么做,它应该提供什么功能


(这是C++但不重要)

qt提供一组类。例如,您可以将树视图挂接到文件系统模型上,并且两个视图都不直接了解彼此(视图中指向模型的指针除外)。

您的需求是:

  • 树显示模型的表示形式
  • 树中的节点可以向模型内的节点发送消息
  • 树根据模型更改重新绘制自身
我不知道您在处理什么样的数据,但是层次模型是一件相当简单的事情。我将把它作为一个已知的例子,让您知道如何迭代层次结构数据并填充树视图

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


最后一个要求比较复杂,取决于一些因素(例如,控制器的生命周期、应用程序体系结构等),我假设控制器的寿命与树视图的寿命一样长。如果是这种情况,那么控制器应该提供一种方法来设置对模型更改的回调。然后,当控制器更改模型时,它可以在不知道UI的情况下回调到UI。

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

模型需要为节点的所有相关参数设置/获取函数。但是这些可以返回简单的类型,因此不依赖于gui

更新模型的视图表单需要发送一条消息,如果您不想让模型知道您的gui消息,那么最好是从树控制器注册一个回调函数(指向函数的无效指针),并调用该函数进行更新。
然后,此更新功能可以查询模型中的更改。

我认为您的问题首先是用词不当。“控制”内容与MVC中的“控制器”没有任何关系。这就是为什么一些GUI库使用其他名称(小部件是常见的名称)

“树控件”是视图,而不是控制器。它应该绑定到GUI,既用于显示,也用于获取GUI事件并将其转换为“树事件”

控制器获取这些“树事件”,并对模型进行必要的修改。这就是将“操作”与“响应”结合起来的地方。

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


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

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

第二种解决方案:引入一个控制器,将模型注册为观察者。从模型接收更新事件后,它可以更新视图。甚至可以在控制器和视图之间使用一个或多个主题观察者模式,将视图与控制器分离

第三种解决方案:使用MVP模式。模型视图演示器。当控制器中并没有太多计算时,即控制器的工作只是更新其相应的视图时,使用此模式。在这里,控制器变成了演示者