保持用户界面最新的最佳方法?

时间:2010-09-08 11:41:04

标签: c++ language-agnostic user-interface consistency

这个问题是我的问题Different ways of observing data changes的改进。

我的C ++应用程序中仍有很多类,它们在复杂的数学例程和复杂的业务逻辑中经常更新(或可能更新)。

如果我采用'观察者'的方法,并在每次更改实例的值时发送通知,我有两大风险:

  • 发送通知本身可能会严重降低应用程序的速度
  • 如果需要通过更改来更新用户界面元素,则每次更改都会更新它们,从而导致例如当某些业务逻辑正在执行时,屏幕正在更新时间

可以通过添加缓冲机制(当您开始使用算法时发送通知,以及算法完成时)来解决某些问题,但由于业务逻辑可能会在许多地方执行软件,我们最终在菜单中选择的每个可能的操作之后几乎到处都添加缓冲。

我还可以使用'mark-dirty'方法代替'观察者'方法,只标记已更改的实例,并在操作结束时告诉用户界面它应该自行更新。 / p>

同样,业务逻辑可以在应用程序内的任何地方执行,因此在实践中,我们可能必须在用户执行的几乎所有操作之后添加额外的调用(告诉所有窗口他们应该自行更新)。

这两种方法似乎都有相似但相反的缺点:

  • 使用'观察者'方法,我们有更多次更新用户界面的风险
  • 使用'mark-dirty'方法,我们有可能无法更新用户界面

这两个缺点都可以通过在每个应用程序操作中嵌入其他逻辑来解决(对于观察者:发送开始结束通知,标记为脏:发送更新自己的通知)。

请注意,在非窗口应用程序中,这可能不是问题。你可以,例如使用mark-dirty方法,只有当某些计算需要数据时,如果数据是脏的,它可能需要做一些额外的处理(这是一种缓存方法)。

但是,对于窗口应用程序,没有信号表示用户正在“查看您的屏幕”并且应该更新窗口。所以没有真正好的时刻,你必须看看脏数据(虽然你可以做一些焦点事件的技巧)。

解决这个问题的好方法是什么?你是如何在你的应用程序中解决这样的问题的?

请注意,我不想在应用程序的计算/数据模型部分引入窗口技术。如果需要窗口技术来解决此问题,则只能在我的应用程序的用户界面部分使用它。

有什么想法吗?

3 个答案:

答案 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观察员只被通知一次。