当一个事件触发应该作用于焦点控件(而不是触发事件的控件)时,您如何在 Model-GUI-Mediator (MGM) 模式中处理这个问题?如果您有多个模型,我怀疑这个问题也适用于密切相关的MVP 模式。
我将此命名为“委托事件”,因为我认为事件发起控件的中介必须将事件委托给选定控件(或其模型)的中介 - 但问题是,“如何?”
背景
MGM 模式有点像MVP Passive View,除了每个控件都有一个单独的“中介”(而不是每个表单一个演示者)。控件的事件全部由其中介处理,中介调用其特定模型的方法作为响应。中介者是模型的观察者,当模型改变时更新它的控制。它特别适用于您的控件没有数据绑定并且您不想对它们进行子类化的 RAD 环境。与被动视图不同,它还有一个优点是连接事件的样板代码很少。这里有两个更详细的描述:
问题示例
一个表单包含许多控件,这些控件提供了许多模型对象的视图。一次只能选择其中一个视图。(如果你想要一些具体的东西,想象一个多文档编辑器。)
用户从菜单调用命令。这将调用特定菜单项的中介对象中的 Execute 方法。(菜单项是一个控件,所以它有一个对应的中介。)
该命令应该对当前选定的控件执行操作。
因此,菜单项的中介需要找到属于所选控件的中介并在那里委托操作,或者需要找到与所选控件的中介关联的模型并直接调用它。
但是菜单项的中介者是如何找到选中控件的中介者的呢?
在 MGM 中,中介对象应该是自包含的,所以不知道其他中介对象。不允许控件了解有关模型的任何信息(以保持关注点的清晰分离)。控件唯一了解其中介者的是事件处理程序。
黑客解决方法
到目前为止,我想出的最好方法是检查所选控件中的事件字段,该字段将是指向该控件中介的对象方法指针。在 Delphi 中,我可以将其转换为 TMethod,从而为控件的中介提取对象指针。然后我可以将其转换为中介的类型并调用所需的方法。
但这似乎严重依赖于语言特性(TMethod),并且还创建了中介类之间的依赖关系。
也许我完全走错了路……</p>
(PS 可以比我有更多代表的人创建一个“model-gui-mediator”标签吗?谢谢。)