这个问题是我的问题Different ways of observing data changes的改进。
我的C ++应用程序中仍有很多类,它们在复杂的数学例程和复杂的业务逻辑中经常更新(或可能更新)。
如果我采用'观察者'的方法,并在每次更改实例的值时发送通知,我有两大风险:
可以通过添加缓冲机制(当您开始使用算法时发送通知,以及算法完成时)来解决某些问题,但由于业务逻辑可能会在许多地方执行软件,我们最终在菜单中选择的每个可能的操作之后几乎到处都添加缓冲。
我还可以使用'mark-dirty'方法代替'观察者'方法,只标记已更改的实例,并在操作结束时告诉用户界面它应该自行更新。 / p>
同样,业务逻辑可以在应用程序内的任何地方执行,因此在实践中,我们可能必须在用户执行的几乎所有操作之后添加额外的调用(告诉所有窗口他们应该自行更新)。
这两种方法似乎都有相似但相反的缺点:
这两个缺点都可以通过在每个应用程序操作中嵌入其他逻辑来解决(对于观察者:发送开始结束通知,标记为脏:发送更新自己的通知)。
请注意,在非窗口应用程序中,这可能不是问题。你可以,例如使用mark-dirty方法,只有当某些计算需要数据时,如果数据是脏的,它可能需要做一些额外的处理(这是一种缓存方法)。
但是,对于窗口应用程序,没有信号表示用户正在“查看您的屏幕”并且应该更新窗口。所以没有真正好的时刻,你必须看看脏数据(虽然你可以做一些焦点事件的技巧)。
解决这个问题的好方法是什么?你是如何在你的应用程序中解决这样的问题的?
请注意,我不想在应用程序的计算/数据模型部分引入窗口技术。如果需要窗口技术来解决此问题,则只能在我的应用程序的用户界面部分使用它。
有什么想法吗?
答案 0 :(得分:2)
我使用的方法是在几年前使用大型Windows应用程序来使用WM_KICKIDLE
。所有可更新的东西都使用名为IdleTarget
的抽象基类。然后IdleTargetManager
拦截KICKIDLE
消息并在已注册客户端列表上调用更新。在您的实例中,您可以创建要更新的特定目标的列表,但我找到了足够的注册客户端列表。
我遇到的唯一问题是使用实时图表。仅使用kick空闲消息,由于图表的不断更新,它会使CPU达到100%。使用计时器睡眠,直到下一次刷新解决了这个问题。
如果您需要更多帮助 - 我的价格合理......: - )
答案 1 :(得分:0)
我在想的另一点。
如果您对生成的事件数量以及可能导致的额外工作感到不知所措,您可能采用两阶段方法:
其中通知仅在提交时发送。
它的缺点是强制重写一些代码......
答案 2 :(得分:0)
您可以使用具有合并的观察者模式。但是,在C ++中实现它可能有点难看。它看起来像这样:
m_observerList.beginCoalescing();
m_observerList.notify();
m_observerList.notify();
m_observerList.notify();
m_observerList.endCoalescing(); //observers are notified here, only once
因此,即使您三次致电notify
,观察员实际上也不会被通知,直到endCoalescing
观察员只被通知一次。