簡體   English   中英

“主人偏好”課是一個好主意嗎?

[英]Is a “master preferences” class a good idea?

我有一個類來管理大型軟件項目的用戶首選項。 項目中可能需要從持久性存儲設置或檢索用戶首選項的任何類都是在此類上調用靜態方法。 這種集中管理允許以編程方式完全擦除首選項 - 如果每個pref都是在接近其使用代碼的情況下處理的話,這將是不可能的。

在此過程中,我遇到了集中化設計的另一個含義。 該軟件具有公共API。 該API可以在jar中自行提供。 該API中的類可能引用pref管理類。 因此,pref管理器必須進入API jar。

每個首選項可能都有一個默認值。 軟件啟動時,可能會計算該默認值。 該算法取決於偏好,因此傾向於駐留在使用代碼附近。 因此,如果pref管理器需要提供默認值,它會調用相關的類。

但是現在pref經理已成為一個“章魚類”,將各種類型的類吸入到不應該存在的API jar中。 如果沒有,那么使用API​​ jar的程序很快會遇到ClassDef異常。 如果確實如此,則API jar現在變得臃腫,因為其他每個類都可能引用其他類。

通常,其他Java程序員是否使用集中式類來管理他們的首選項?

將靜態pref管理類作為公共API的一部分進行分發是否有意義?

該pref經理是否應該成為確定默認值的代碼的守護者?

恕我直言,我認為你的第一個問題的答案是“是”和“否”。

首選項通常作為集中式類處理,因為類是項目中許多類的“接收器”。 嘗試更接近調用代碼意味着如果相同的首選項稍后在其他地方有用,則會遇到麻煩。 根據我的經驗,嘗試將偏好設置為“太近”也會導致處理非常不一致。

話雖如此,通常最好使用多個偏好類或“偏好集”,每個偏好類或“偏好集”支持模塊或子模塊。 如果查看體系結構的主要組件,通常會發現可以對這些首選項進行邏輯分區。 這減少了每個偏好類中的混亂。 更重要的是,它允許您將來將程序拆分為多個罐子。 現在,“默認值”計算器可以放在模塊中,但仍然位於足夠全局的區域。

我還建議不要將首選項直接設置為靜態方法,而是使用一些類似getInstance()的操作來獲取首選項管理的共享實例,然后對其進行操作。 根據您的語義,您可能希望鎖定該對象一段時間(例如,當用戶在UI中編輯首選項時),如果您有實際對象,這將更容易。

對於您的其他問題,我會說您的公共API應該有一種讓用戶更改首選項的方法,但前提是您可以很好地記錄這些更改的結果。

如果您使用單個API函數來獲取“參考管理器”,則可以為用戶提供自己的“默認值計算器”。 首選項管理器將首先詢問此計算器,然后再使用您默認提供的計算器。

難道你不能以一種非常通用的方式處理偏好嗎? 然后,您只需使用首選項管理器來處理持久性。 所以從一個類你只需要說一下偏好管理器PreferenceManager.setPreference(key,value),它就不關心它在數據語義方面的節省。

還是我太簡單了?

我不是Java Dev,但就整個“章魚類”而言,你能不能只為jar提供一個接口,並在運行時連接接口和prefs管理器之間的調用,使用應用程序配置文件確定prefs管理器實例化?

像.NET提供者模式的東西?

這樣你就可以將你的jar與prefs管理器分離。

您可能希望查看Cocoa的NSUserDefaults類以獲得靈感。 它通過具有多層首選項(稱為域)來處理您描述的問題。 當您查找鍵的值(例如“PrintUsingAllCaps”)時,它首先檢查用戶本地域中的值。 如果在那里找不到它,它可以檢查系統范圍的域,或網絡級域,等等。

它檢查的絕對最后一個位置稱為“注冊域”,這基本上是硬編碼默認值應該去的地方。 因此,在我的代碼中的任何一點,我都可以在注冊域中寫一個首選項,並且NSUserDefaults只會在用戶沒有覆蓋它的情況下提供該值。

因此,在您的情況下,您可以為類提供一種方法,以便在訪問(可能)用戶定義的值之前為其設置默認值。 首選項類不必知道它所服務的類的任何信息。

正如其他人建議的那樣,如果你需要更復雜的東西,你可以設置一個DefaultValueProvider回調對象而不是一個直值。

JSR-10( java.util.prefs.* )API使用帶有Class<?>參數的工廠方法來創建Preferences實例。 這樣,API可以將屬於同一包的不同類的首選項存儲在單個文件中。

我刪除了第一個答案,因為我誤解了作者的要求。

要真正解決實際問題 - 感覺就像您希望將偏好(以及默認值的計算)與使用它們的代碼放在一起是有意義的。

您是否可以通過為每個區域使用首選項容器類來滿足這兩個要求,該區域遵循該區域的模式,但是讓它注冊“全局”首選項對象集合?

您的全局集合可以執行諸如迭代每組首選項並將其重置為默認值的操作,但您的首選項本身仍將在本地定義和維護,以便它不會分散到代碼的其他部分。

我能看到的唯一問題是,如果您允許首選項對象在實例化時注冊自己,那么您可能會嘗試“重置為默認值”,而某些首選項尚未實例化。

我想這可以通過讓主“首選”類實例化所有其他類來解決,然后任何一段代碼都可以通過靜態getter從中央首選項中檢索它的本地首選項對象。

這似乎與一些記錄器的工作方式非常相似。 有一個維護日志級別,輸出流等的中央機制,但每個類都有自己的“日志”方法實例並記錄到它。

我希望這更符合目標。 哦,我也同意接受的答案,不要讓你的所有方法都是靜態的,總是使用吸氣劑 - 你會很高興你有一天做的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM