0

In this link: http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx it says:

Singletons frequently are used to provide a global access point for some service. True, they do this, but at what cost? They provide a well-known point of access to some service in your application so that you don't have to pass around a reference to that service. How is that different from a global variable? (remember, globals are bad, right???) What ends up happening is that the dependencies in your design are hidden inside the code, and not visible by examining the interfaces of your classes and methods. You have to inspect the code to understand exactly what other objects your class uses. This is less clear than it could be.

I'm trying to understand what the difference is between this and having a reference to our object in many locations. If we have a reference held somewhere else, then couldn't our object be modified in some totally different location, say by some other thread, and be just as hard to reason about?

vmayer
  • 985
  • 2
  • 9
  • 18

1 Answers1

1

There isn't a lot of differences between a singleton and a global variable. The biggest difference is that a singleton of class T allows only one globally available instance of class T available everywhere, whereas having a global instance of T doesn't restrict the program from creating more instances of T.

The issue that the snippet is talking about is an issue of decoupling the actual singleton from any code that uses the singleton. If you're writing class Foo, ideally you would want to design the class where all the necessary information about how Foo can be used is available in the interface. Now if Foo uses Singleton Bar, this is part of Foo's implementation. If a user sees no need to have Bar and removes the class definition from the program, they would suddenly see that Foo doesn't compile, and it's not inherent why just by looking at Foo's interface. They would have to actually look through the implementation and see the code that grabs the singleton instance and uses it.

You would run into the exact same issue with global variables as well if class Foo were to use a globally available instance of Bar, but there's a small difference about it. If Foo contains a reference to the global variable inside itself, then the fact that it uses an instance of Bar is inherent in the interface, and the user of Foo would at least understand that it is dependent upon Bar, whereas the global singleton is always available and uncopyable, so it is likely that the writter of Foo would store the reference to the singleton, and the relationship would not be inherent from the interface.

Now, there are a lot of other issues about using global variables in general, for example Unit Testing Foo. If for some reason Bar were to fail a unit test for one of its common functionalities, then most likely Foo would also fail its unit tests for functions that use the singleton/global Bar, even if the Foo function itself is written perfectly.

Singletons are marginally worse than global variables as far as making clear interfaces goes due to not implying the relationship to Bar, but the article you linked is likely arguing that you should avoid both Singletons and global variables.

  • Thanks for spelling it out. I did get a little confused about your use of the term "global variables", however. You don't mean variables that are explicitly global per se, do you? But rather variables which have references in multiple places throughout the code (per my question), right? – vmayer Feb 25 '16 at 15:42
  • 1
    I was using the term global variable because I made an assumption that you were just using references to a global variable instead of using a Singleton, which is equally as bad. Now, if you either store a reference to a variable inside the class or you pass in the variable as a parameter into the function using the variable, that is considerably better than a singleton/global because it then becomes clear in the interface of the class the relationship between the class holding the reference Foo, and the class it holds a reference to Bar. – Kyle Larson Feb 26 '16 at 00:12