2
\$\begingroup\$

I've been developping a 3D app for some time and I remember at some point I started to need to pass data arround in unrelated areas of the program, where it wouldn't make much sense to pass them through update functions (stuff like screen resolution or cursor position). My solution at the time was to implement a "Ressources" singleton class that would hold and manage all that data. But now looking back at my code I don't intuitively see the difference between a singleton and a static class. I'm tempted to switch to static implementation, since it would mean I wouldn't have to fetch the singleton eveytime I want to use it, but I'm curious what more experienced programmers have to say about this.

I did look a bit arround for other's opinions, but what's been surfacing is that the very minute differences used in very corner-cases implementations are emphasized everywhere and overall I can't find a general preference for one or the other. Add to that that Java coders tend to hate non-OOP programming and they tend to just say: global variables are bad, period. So I'm left a bit confused here.

Is there really an advantage to use one or the other in my general case, or is it just functionaly the same? Are there performance benefits? Are there code structure benefits?

\$\endgroup\$
1

1 Answer 1

5
\$\begingroup\$

In Game Programming Patterns, Robert Nystrom lays out that there's a few common reasons we like to reach for singletons:

  • Ease of global access

  • Only takes resources if used (if no one uses the singleton in a given run, we can avoid instantiating it)

  • You can control when it's instantiated, and it can be customized with runtime information (e.g. instantiating a different subclass or initializing it with a different configuration depending on information only known after launch)

  • Enforced uniqueness (no risk of different bits of code each trying to spin up their own version and conflicting with each other)

He points out that several of the problems we run into singletons mostly arise when we only want some of those traits, but we reach for a solution with all of them and end up fighting.

Here, you don't care about points #2 and 3. You're always going to need information about the cursor, so there's no benefit to lazily instantiating this, and you don't need to decide between polymorphic cursor behaviours at runtime.

So, a singleton is overkill here, and a static class gets you the traits you care about (global access and uniqueness) more simply.

Yes it's introducing mutable global state, but so is a singleton, so there's no particular encapsulation win by making this an instance. You can arrange your interface so that data is accessed through getters to limit the ways it can be mutated to the correct pathways.

Using static classes this way is not unusual in game development. Most of the Unity API for example is accessed this way, through static classes for Time, (legacy) Input, Screen, SceneManager, etc.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .