Saturday, March 23, 2019

architecture - Alternatives to Singletons / globals


I've heard countless times about the pitfalls of Singletons / globals, and I understand why they're so often frowned upon.


What I don't understand is what the elegant, non-messy alternative is. It seems that the alternative to using Singletons/globals always involves passing objects a million levels down through your engine objects until they reach the objects that need them.


For example, in my game, I preload some assets when the game starts up. These assets aren't used until much later when the player navigates through the main menu and enters the game. Am I supposed to pass this data from my Game object, to my ScreenManager object (despite the fact that only one Screen actually cares about this data), then to the appropriate Screen object, and anywhere else?


It just seems that I'm trading global state data for cluttered dependency injection, passing data to objects that don't even care about the data except for the purpose of passing it on to child objects.


Is this a case where a Singleton would be a good thing, or is there some elegant solution I'm missing?




Answer



Don't conflate singletons and globals. While some kind of global variables are usually necessary, the singleton is not just a replacement for a global variable, but primarily a way to work around problems of static initialization order in C++ (and FQA). (In other languages, it's a way to work around different language deficiencies, like the lack of global variables and bare functions.)


If you can just use a global pointer instead of a singleton, and make sure it's initialized (manually) before anything needs it, you avoid the function call and branch overhead, the lame syntax to get at the object, and you can actually make a second instance of the class when you need to for tests or because your design changed.


For the few global variables you want (common examples being audio output, list of open windows, keyboard handler, etc.), I recommend the service locator pattern. It makes it easy to replace things with different implementations (e.g. real vs. null audio device), and collects all your globals into one structure to avoid polluting your namespace.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...