我正在编写一个XNA引擎,并将所有模型存储在List
中。为了能够在整个引擎中使用它,我制作了这个public static List<Model>
,这样我就可以从我开发的任何新类中访问它。它确实使获得模型列表真的很容易得到,但这是正确的用法?或者,我真的会更好地在一个方法声明中传递一个变量吗?我是否以正确的方式使用静态?
回答
在OOP中,通常建议避免使用静态方法和属性,除非您有足够的理由这样做。其中一个原因是,将来您可能会因某种原因想要拥有两个或更多此列表实例,然后您将被静态调用阻止。
静态方法和属性过于僵化。如Stevey所述:
静态方法与 花岗岩一样灵活。每当你使用一个, 你正在铸造你的程序的一部分在 具体。只要确保你没有 你的脚在那里卡住 你正在看它变硬。有一天你 会惊奇地发现,通过天哪,你 真的需要那宕PrintSpooler类的另一种实现方式 ,并 它应该是一个接口, 工厂,以及一组实施 类。 D'哦!
我会建议实现封装模型列表的Singleon对象。
看看MSDN singleton implementation。
单身人士有其自身的缺点,实际上他们与静态方法的对象并无太大区别。这里有一篇关于它的文章:http://sites.google.com/site/steveyegge2/singleton-considered-stupid通常最好创建一个对象并将其作为参数传递给需要使用它的任何人。 – 2011-04-04 07:58:51
这是平衡和取舍的问题。
当然,面向对象的纯粹主义者会说,不惜一切代价避免这样的全局变量,因为它通过引入一些对于任何模块“开箱即用”的东西来破坏代码分隔,从而使得难以维护,改变,调试等
但是,我个人的经验是,应该避免只有当你是一个非常大的企业解决方案团队的一部分,保持一个非常大的企业级应用。
对于其他人的情况下,全球封装可访问的数据变成了“全球”的对象(或静态对象,同样的事情)简化OOP编码很大程度上。
你可能会得到中间接地通过写入全球GetModels()函数返回的型号列表。或者使用DI自动注入模型列表。
小型项目可以稍后变大。即使是最小的项目也应该是可测试的。静力学是单元测试的敌人。 – 2011-04-04 08:34:09
@FrantišekŽiačik,好点! +1这就是为什么我提到他可能需要有一个GetModels()函数,这样才能在单元测试中注入一个虚拟物... – 2011-04-04 08:44:40
@FrantikšekŽiačik,然而,在游戏开发中,通常会有大量的全局数据(如板卡数据,地形数据,玩家数据等)在码流之间进行同步。实际上,全球数据通常远远超过非全球数据。所以必须有某种形式的平衡。 – 2011-04-04 08:48:54
我会避免使用静态尽可能,随着时间的推移,你会刚刚结束了spaghetti code。
如果您通过它在构造你省去不必要的依赖,low coupling is good。依赖性越少越好。
对于游戏开发,我提倡“做最可能工作的最简单的事情”。这包括使用全局变量(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
函数。这将你对静态的使用划分为单独的类,而不是使用从整个程序中访问的全局(以后很难解析)。它还能正确处理正确时间的加载内容。
- 1. 我是否正确使用静态?
- 2. 使用“最终静态”还是“静态最终”是否正确?
- 3. 我是否以正确的方式使用了cython?
- 4. 我是否以正确的方式使用ID转换?
- 5. 我是否正确使用* ngFor方法?
- 6. 正确使用静态方法
- 7. 这是否以正确的方式使用Log4j Hadoop?
- 8. 我使用$?是否正确?
- 9. 以静态方式
- 10. 静态存储库是使用NHibernate的正确方法吗?
- 11. 我正在写我的Vue组件的方式是否正确?
- 12. Java:是否有正确的方法来使用静态易失性变量?
- 13. 以这种方式在Prolog中使用'if'是否正确?
- 14. 我是否以正确的方式构建我的应用程序? - Backbone.js
- 15. 在静态模式下使用AudioTrack的正确方法是什么?
- 16. 是否可以使用最终的静态类方法?
- 17. 我正在以正确的方式更新状态?
- 18. 如何以静态和非静态方式使用枚举
- 19. 类方法可以是内联方式还是静态方式?
- 20. PHP - 是否可以声明静态和非静态方法
- 21. 如何正确使用Mockito静态方法包装在非静态方法中?
- 22. 以怪异的方式编写的方法,我的建议是否正确?
- 23. 使用反射,我可以确定Java静态最终字段是否内置?
- 24. 在java中的静态方法,我可以以非静态方式访问静态方法吗?
- 25. C:正确的方式来静态/动态链接使用MinGW-W64
- 26. 以正确的方式使用线程
- 27. DAO模式 - 使用静态还是非静态方法?
- 28. 不正确的使用静态变量?
- 29. 我应该使用静态方法还是静态字段
- 30. 是否正确的方式鳕鱼?
你使用任何一种线程?如果是这样,那么你真的想避免一个静态列表。 – Marthin 2011-04-04 07:59:11
@Marthin:没有使用线程。 – 2011-04-04 08:07:24
然后从我的体验中,我认为只要知道它是一个相当小的项目,就可以继续使用静态列表。但是,如果你认为这可能会增长,那么我会建议去工厂。工厂对于所有这些类型的实施来说都不是最佳的,但对我来说,它们有助于使植入更容易并且变得非常方便。最后提示:由Joshua Bloch阅读Effective Java。所有程序员Java,.NET等的最佳实践=)GL! – Marthin 2011-04-04 08:39:36