c ++“双向”观察者模式

时间:2010-11-24 13:07:53

标签: model-view-controller user-interface bidirectional observer-pattern

我一直在阅读如何在C ++应用程序中实现适当的MVC,并且基本上已经有两种方法可以实现这一点:

  • 观察者模式
  • signal / slot

然而,在这两种情况下,我读到的所有例子都遵循一个结构,在这个结构中主体可以改变并通知它的观察者,但观察者从不改变主题。现在这种情况出现了一些“问题”。

假设我有一个名为Text(一个模型组件)的类,另一个名为TextEditor(一个GUI组件)的类,它可以显示'Text'并且应该能够修改它和其他一些可以修改'Text的类'以及。

是的,所以我使用观察者模式,使'Text'成为主题,'TextEditor'成为观察者。没什么大不了的。

如果以某种方式更改“文本”,Text调用Text :: notify(),我的TextEditor将反映更改。精细。

现在,如果我使用TextEditor修改文本怎么办?

'TextEditor'知道'Text',因此它调用类似textInstance.setText(...)的内容 ...并且在setText的末尾,'Text'调用notify,并且'TextEditor'被告知它自己做出的更改! 'Text'甚至不能向除'TextEditor'之外的所有人发送通知,因为它不会想知道它的观察者!

我觉得这是不对的,而不是“干净”甚至性能原因的帮助。 我敢打赌,有一个更好的方法来实现这个,但我被卡住了。有人有提示吗?

我不是真正想要预先制作的C ++实现,而是更多地了解我应该如何正确地看待事物。

1 个答案:

答案 0 :(得分:4)

图案很干净。你现在正在做出比TextEditor更多的假设,因为setText正在做什么,所以不需要通知。如果文本已被冻结并拒绝自行修改,该怎么办?文本也可以是一种记录器,它附加任何新文本并添加时间戳等。

因此,对于TextEditor来说,“要求”Text做某事然后检查结果是什么,这是完全干净的。 因此,TextEditor不会收到有关其自身更改的通知,而是通知它所要求的更改是如何管理的。

如果你确实遇到了性能问题,你可以用不同的方式破解观察者模式

  • 在调用sendText并在之后读取
  • 之前删除TextEditor作为观察者
  • 如果所有调用都是同步的:通过设置属性
  • 来阻止TextEditor自动刷新
  • 等...