单例比静态更好?
所以我的游戏中有一个玩家类别。从逻辑上讲,只需要一个玩家对象(单个玩家),但许多不同的类需要访问该玩家对象。 (即,地图需要知道玩家是谁,摄像机和敌人需要与玩家交互等)。
我有几个选择。
要么我可以将这个播放器对象传递给所有需要它的东西,但这很麻烦。 (我认为它被称为依赖注入)
只需将其设为公共静态即可。
使其成为单例。
各自的优点/缺点是什么?
So I have a player class in my game. Logically there only needs to be one player object (single player) But a lot of different classes need access to the player object. (ie, maps needs to know were player is, as does camera and enemies need to interact with the player, etc).
I have a couple of options.
Either I could pass this player object around to everything that needs it which is cumbersome. (Dependency injection I think it's called)
Just make it public static.
Make it a singleton.
What are the pros/cons of each?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我不会在这里使用 Singleton 或静态变量,而是通过 setter 将
Player
实例传递给需要它的类。如果您只需要一个播放器实例 - 只需调用new Player()
一次:-)请参阅我对单例的看法 这里。简短摘要:它们典型的误用(避免“麻烦的”设置器)违反了面向对象并降低了设计质量。
静态变量与单例一样,以及 Monostate (非静态 getters ,静态数据,构造函数是“工厂”)。避开他们。考虑一下是否将所有内容都设为静态:玩家、地图、摄像机、敌人等。您将避免很多“麻烦”的设置器。但这是OO吗?当你完成你的游戏时,你可以在另一个游戏中重用你的寻路算法、AI算法等,或者它们是否有太多特定于你当前游戏的全局变量(Singletons等)永远烧录在它们中?
I would not use a Singleton or static variable here and instead would hand a
Player
instance to the classes that need it via setters. If you only need one player instance - only callnew Player()
once :-)See my take on Singletons here. Short summary: their typical misuse (avoiding "cumbersome" setters) violates OO and lowers design quality.
Static variables are cut from the same cloth as Singletons, along with the Monostate (non-static getters, static data, constructor is the "factory"). Avoid them. Consider if you made everything static: player, map, camera, enemies, etc. You would avoid a lot of "cumbersome" setters. But is it OO? When you finish your game can you reuse your pathfinding algorithms, AI algorithms, etc. on another game, or do they have too many global variables (Singletons et al) specific to your current game burned into them forever?
所以,你的选择是:
两者都会有效地将其变成全局变量。我不太喜欢全局变量:它们让一切都变得更难测试和调试。
优点:更容易访问
缺点:耦合度非常高(如果你想让它成为一个两人游戏怎么办?);增加了测试的复杂性;改变一个地方的球员可能会对其他地方产生意想不到的后果。
优点:低耦合;方便测试;您可以将播放器的副本传递给其他类并减少副作用的可能性。
缺点:必须传递
Player
引用会使 API 变得更加复杂,但可以通过使用依赖项注入框架(例如 Guice。So, your options are:
Both would effectively turn it into a global variable. I'm not a big fan of globals: they make everything harder to test and debug.
Pros: Easier access
Cons: Very high coupling (what if you want to make it a two player game?); Adds complexity to tests; Changing the player in one place might have unexpected consequences on other places.
Pros: Lower coupling; Facilitates testing; You can pass copies of the player to other classes and reduce the chances of side-effects.
Cons: Having to pass
Player
references makes the API a bit more complex, but part of it may be mitigated by using a dependency injection framework, such as Guice.除了 Java Setter 和 Getter 提供的优势之外,我真的想不出任何新的单例模式(
public static Type getInstance()
)将为您提供公共变量(public static Type var
)。但总的来说,控制对成员变量的访问(尤其是从外部将其作为成员变量的类)总是更好(从未来的观点来看),所以我建议使用
private static< /code> 带有公共 getter 的变量。它介于单例和公共静态变量之间。
Apart from teh advantages provided by Java Setter and Getter, I can't really think of any new ones that a singleton pattern (
public static Type getInstance()
) would give you over public variable (public static Type var
).But in general it's always better (from future pov) to control access to member variables (especially access from outside the class that has this as member variable), so I would recommend a
private static
variable with a public getter. Which is somewhere between a singleton and a public static var.使用单例使您可以扩展基类并提供 Player 的替代实现,使用静态方法现在可以实现这种灵活性。
另一点是,“概念上”玩家是一个对象而不是一个类。
Using a singleton gives you the possibility to extend the base class and provide alternative implementations of Player, using a static method does now allow that flexibility.
Another point is that "conceptually" a player is an object and not a class.
我会避免使其静态。您希望您的代码可重用,并且玩家肯定是一个可能需要备用项目中的多个实例的对象。
我将创建简单的 getAttribute()、editAttribute 方法来返回或编辑我需要的属性。
另一种选择是简单地将可共享属性在玩家类中公开,尽管我更喜欢获取/编辑方法选项。
I would avoid making it static. You want your code to be reusable and a player is certainly an object that may require several instances in an alternate project.
I would create simple getAttribute(), editAttribute methods that return or edit the attribute I need.
Another option would be to simply make the shareable attributes public within the player class although I would prefer the get/edit methods option.
单例可以实现可用于引用单例的接口。即,您不需要在整个代码中硬编码对单例的引用。如果您想要使用不同的实例进行测试,这会使单元测试变得更加容易。
Singletons can implement interfaces which can be used to refere to the singleton. i.e. you don't need hardcoded references to a singleton throughout your code. This makes unit testing easier, if you want a different instance for testing purposes.