2011-04-04 73 views
5

我正在編寫一個XNA引擎,並將所有模型存儲在List中。爲了能夠在整個引擎中使用它,我製作了這個public static List<Model>,這樣我就可以從我開發的任何新類中訪問它。它確實使獲得模型列表真的很容易得到,但這是正確的用法?或者,我真的會更好地在一個方法聲明中傳遞一個變量嗎?我是否以正確的方式使用靜態?

+1

你使用任何一種線程?如果是這樣,那麼你真的想避免一個靜態列表。 – Marthin 2011-04-04 07:59:11

+0

@Marthin:沒有使用線程。 – 2011-04-04 08:07:24

+0

然後從我的體驗中,我認爲只要知道它是一個相當小的項目,就可以繼續使用靜態列表。但是,如果你認爲這可能會增長,那麼我會建議去工廠。工廠對於所有這些類型的實施來說都不是最佳的,但對我來說,它們有助於使植入更容易並且變得非常方便。最後提示:由Joshua Bloch閱讀Effective Java。所有程序員Java,.NET等的最佳實踐=)GL! – Marthin 2011-04-04 08:39:36

回答

5

在OOP中,通常建議避免使用靜態方法和屬性,除非您有足夠的理由這樣做。其中一個原因是,將來您可能會因某種原因想要擁有兩個或更多此列表實例,然後您將被靜態調用阻止。

靜態方法和屬性過於僵化。如Stevey所述:

靜態方法與 花崗岩一樣靈活。每當你使用一個, 你正在鑄造你的程序的一部分在 具體。只要確保你沒有 你的腳在那裏卡住 你正在看它變硬。有一天你 會驚奇地發現,通過天哪,你 真的需要那宕PrintSpooler類的另一種實現方式 ,並 它應該是一個接口, 工廠,以及一組實施 類。 D'哦!

0

我會建議實現封裝模型列表的Singleon對象​​。
看看MSDN singleton implementation

+1

單身人士有其自身的缺點,實際上他們與靜態方法的對象並無太大區別。這裏有一篇關於它的文章:http://sites.google.com/site/steveyegge2/singleton-considered-stupid通常最好創建一個對象並將其作爲參數傳遞給需要使用它的任何人。 – 2011-04-04 07:58:51

0

這是平衡和取捨的問題。

當然,面向對象的純粹主義者會說,不惜一切代價避免這樣的全局變量,因爲它通過引入一些對於任何模塊「開箱即用」的東西來破壞代碼分隔,從而使得難以維護,改變,調試等

但是,我個人的經驗是,應該避免只有當你是一個非常大的企業解決方案團隊的一部分,保持一個非常大的企業級應用。

對於其他人的情況下,全球封裝可訪問的數據變成了「全球」的對象(或靜態對象,同樣的事情)簡化OOP編碼很大程度上。

你可能會得到中間接地通過寫入全球GetModels()函數返回的型號列表。或者使用DI自動注入模型列表。

+2

小型項目可以稍後變大。即使是最小的項目也應該是可測試的。靜力學是單元測試的敵人。 – 2011-04-04 08:34:09

+0

@FrantišekŽiačik,好點! +1這就是爲什麼我提到他可能需要有一個GetModels()函數,這樣才能在單元測試中注入一個虛擬物... – 2011-04-04 08:44:40

+0

@FrantikšekŽiačik,然而,在遊戲開發中,通常會有大量的全局數據(如板卡數據,地形數據,玩家數據等)在碼流之間進行同步。實際上,全球數據通常遠遠超過非全球數據。所以必須有某種形式的平衡。 – 2011-04-04 08:48:54

5

對於遊戲開發,我提倡「做最可能工作的最簡單的事情」。這包括使用全局變量(C#中的public static),如果這是一個簡單的解決方案。你可以隨時把它變成更正式的東西。 Visual Studio中的「查找所有引用」工具使得這非常簡單。

這就是說,很少有情況下全局變量實際上是「正確的」做某事的方式。所以如果你打算使用它,你應該知道和瞭解的正確解決方案。因此,您可以在「懶惰」和「編寫好代碼」之間做出最佳折中。

如果你打算做一些全球性的事情,你需要完全理解爲什麼你這樣做。

在這種特殊情況下,這聽起來像是在試圖獲取內容。你應該知道ContentManager將自動返回相同的內容對象,如果你多次要求它。因此,不要將模型加載到全局列表中,請考慮通過您的Game類的public static屬性使您的Game類的內置ContentManager可用。

或者更好的是,有一種我更喜歡的方法,我認爲它更好一些:I explain it in the answer to another question。基本上,您在使用它們的類中將內容引用爲private static,並將ConentManager傳遞給public static LoadContent函數。這將你對靜態的使用劃分爲單獨的類,而不是使用從整個程序中訪問的全局(以後很難解析)。它還能正確處理正確時間的加載內容

相關問題