1

我有一個客戶端/服務器問題,我試圖找出最佳解決方案。如果發生錯誤,IO線程警告GUI線程

如果客戶端與服務器斷開連接,出於任何原因,我想讓輸入輸出線程警告gui線程出錯,從而讓gui線程打印錯誤並正常處理它(可能會退回到登錄gui)。在初始的gui線程創建後,客戶端可以更改爲任何數量的guis,具體取決於他在做什麼,所以我想我需要一種方法來動態地查看當前正在運行的gui。

,我想這樣做,到目前爲止的方法:

1)創建,創建並顯示每個GUI對象。所以,而不是調用invokeLater ... SomeGui.CreateAndShoGui()...我們會有這個對象負責這樣做,即GuiObject.showSomeGui();

2)讓每個GUI都實現一個接口,這將確保有一種方法在被調用時會在我們失去與服務器的連接時正常關閉此GUI。

3)有一個線程監視IO線程和gui對象。如果IO線程出現問題,IO線程將關閉並通知監視線程我們已經失去連接服務器。然後,監控線程可以警告任何開放的guis(來自gui對象)我們已經失去連接並且需要關閉。

我剛開始考慮這個問題,到目前爲止,這是我提出的最佳解決方案。這似乎是一個合理的解決方案,不會給代碼增加太多的複雜性?或者任何人都可以推薦一種解決方案,讓閱讀代碼的人更容易理解?

感謝

編輯: 我與正在發生IO線程,因爲它打開也被傳遞給每一個新的圖形用戶界面上的對象玩弄另一種選擇。該對象將當前打開的guis引用返回給io線程,以便io線程可以在出現問題時提醒它。雖然我傾向於這個解決方案,因爲如果你有一個專門用來實現這個工作的對象(比如上面的解決方案),而不是將一些不明確的對象傳遞給每個gui,它似乎會更容易閱讀。

回答

2

讓我走您的每個想法:

1)壞主意 - 你是通過一個單一的對象綁在一起,你的整個應用程序。這使得維護性變得困難並且是模塊化的對立面。

2)這是去恕我直言的方式。由於看起來每個gui在失敗場景中都有獨特的邏輯,因此理解最能理解要做什麼的對象就是gui對象本身。

這個想法的另一個版本是爲每個GUI創建一個適配器來將這個失敗邏輯放入。好處是你的應用程序框架和你的gui之間少了一個依賴關係。缺點是這是一個額外的複雜層。如果你的GUI已經和你的應用程序耦合了,那麼我會選擇接口方法。如果您想在其他應用程序中重複使用guis,那麼適配器方式可以幫助實現這一點。

3)這很好地補充了#2。所以讓我弄清楚這一點 - 你將有3個線程:IO線程,監視器線程和UI線程。我不知道你是否需要顯示器線程。從你所說的IO線程本身可以檢測到連接問題(可能是因爲某種形式的IOException被捕獲)。當發現連接問題時,IO線程並不忙,因爲它只是即將關閉它,所以它可能只是有責任通知guis有問題。 guis應該在UI線程上調用它們的接口方法,因此IO線程只是調用一堆invokeLater()調用(或者SWT的asyncExec()調用),然後IO線程可以關閉它。

4)(您的編輯)您基本上描述訪客模式。我不認爲這是一個好的解決方案,因爲這個調用是從IO線程到GUI而不是其他方式。我不確定在這種情況下如何傳遞訪客對象會有所幫助。

最後一個想法。如果你使你的接口是通用的(而不是gui特定的),那麼你可以將這個模式應用到其他資源。例如,你可能想在你失去連接時刷新你的用戶憑證(因爲你談到了再次登錄屏幕)。這不是真正的貴族邏輯,不應該由貴族階級來完成。

編輯:我會使用事件模型。比方說,你創建一個這樣的接口:

public interface ConnectionFailureListener { 
    void handleConnectionFailure(); // Add an event object if you need it 
} 

然後,您可以在某個對象(也許是可運行的IO線程或者其他更爲方便你)登記方法。這些方法是非常標準:

public void addConnectionFailureListener(ConnectionFailureListener l) {} 
public void removeConnectionFailureListener(ConnectionFailureListener l) {} 

當你在屏幕上顯示一個圖形用戶界面,你會添加到您的註冊對象,當你關閉GUI,你會從註冊的對象中刪除。您可以根據需要添加其他類型的對象 - 例如,登錄時,您可以爲您的憑證系統添加偵聽器,並在處理註銷時再次將其移除。

這種方式,當你有一個失敗的情況下,你只需循環通過當前註冊的監聽器和監聽器做它的事情。

+0

我的下一個問題是,如果每個GUI都實現了一個接口,那麼IO線程如何知道要調用closeGui方法?任何數量的不同的guis都可能會起作用,如果我沒有誤認爲IO線程必須引用當前的gui才能調用該方法?或者有什麼我在這裏失蹤? – vimalloc 2010-08-20 16:19:20

+0

請參閱編輯回覆後的信息。 – rancidfishbreath 2010-08-20 20:06:41