2010-09-08 136 views
2

這個問題是我的問題Different ways of observing data changes的改進。保持用戶界面最新的最佳方式?

我的C++應用程序中仍然有很多類,這些類在複雜的數學例程和複雜的業務邏輯中經常更新(或可以更新)。

如果我去的「觀察員」的方式,每一個實例的值發生改變時發出通知,我有2點大的風險:

  • 送出本身的應用減慢通知嚴重
  • 如果用戶界面元素需要通過更改進行更新,它們會隨着每次更改而更新,從而導致例如正在執行一些業務邏輯的屏幕正在執行時間

有些問題可以通過添加緩衝機制來解決(當您打算以算法開始時發送通知,以及當算法已完成),但由於業務邏輯可能會在軟件中的許多地方執行,因此我們最終會在菜單中選擇的每個可能操作後添加緩衝區。

除了'觀察者'的問題,我還可以使用'mark-dirty'方法,只標記已被修改的實例,並在操作結束時告訴用戶界面它應該自行更新。業務邏輯可以從應用程序中的任何地方執行,因此實際上在用戶執行幾乎每一個動作之後,我們可能不得不添加額外的呼叫(告訴所有窗口它們應該自己更新)。

兩種方法似乎都差不多,但相反的缺點:

  • 隨着「觀察員」的方法,我們必須更新用戶界面的風險太多次
  • 隨着「標記髒」的方法,我們必須在所有

兩個缺點可以通過額外的邏輯中嵌入每一個應用程序的行動(觀察員來解決不更新用戶界面的風險:發出啓動結束的通知,對於標記髒:發送更新 - 你自己的通知)。

請注意,在非窗口應用程序中,這可能不是問題。你可以例如使用mark-dirty方法,只有當某些計算需要數據時,它可能需要做一些額外的處理以防數據變髒(這是一種緩存方法)。

然而,對於窗口應用程序,也沒有信號,用戶在「看你的屏幕」和窗戶應更新。所以沒有真正的好時機,你必須查看髒數據(儘管你可以用焦點事件做一些技巧)。

解決此問題的最佳解決方案是什麼?你是如何在你的應用程序中解決這樣的問題的?

請注意,我不希望我的應用程序的計算/數據模型部分介紹了窗技術。如果需要開窗技術來解決這個問題,它只能用在我的應用程序的用戶界面部分。

有什麼想法?

+0

觀察者是否可以設置一個事件或喚醒等待事件的線程的東西。這是這個線程,然後接管通知所有用戶界面 – Chubsdad 2010-09-08 12:39:24

回答

2

我使用的一種方法是用幾年前的大型Windows應用程序使用WM_KICKIDLE。所有可更新的東西都使用一個稱爲IdleTarget的抽象基類。然後IdleTargetManager攔截KICKIDLE消息並在註冊客戶列表上調用更新。在你的實例中,你可以創建一個特定的目標列表來更新,但我發現足夠的註冊客戶端列表。

我碰到的唯一問題是實時圖形。由於圖形的不斷更新,僅使用踢空閒消息就會使CPU達到100%。使用計時器休眠,直到下一次刷新解決該問題。

如果您需要更多幫助 - 我可以以合理的價格... :-)

+0

好主意的工作。它有什麼好處,它清楚地將業務邏輯部分(根本不知道任何用戶界面)與用戶界面部分分開。 – Patrick 2010-09-08 12:34:12

0

還有一點,我在想什麼。

如果您是通過生成的事件的數量,並可能是導致額外的工作壓得喘不過氣來,你可能有兩個階段的辦法:

  • 做的工作
  • 提交

其中通知只在提交時發送。

它有強迫重寫一些代碼的缺點...

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當觀察員只通知一次。