2011-04-04 38 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函数。这将你对静态的使用划分为单独的类,而不是使用从整个程序中访问的全局(以后很难解析)。它还能正确处理正确时间的加载内容

相关问题