Chris Donnan : Programming – Brooklyn Style
software, trading, family, fun
Posted programming on Friday, June 2nd, 2006.
I was having more – anti-static debate today with a collegue. It is interesting to me – my collegue is really bright – I will update my opinion if it changes – but I bet he is a great software developer. Those are rare. That said – he loves the static thing
So – naturally – we have been having some “healthy debate”. Who knows – maybe he will compel me with some of his view-points. Perhaps – as I have with others – I will compel them with my view-points.
As I mentioned the other day – statics are globals… as Stanley Lippman put it:
o The functions that utilize the global variable depend on the existence and type of that global variable, making the reuse of that function in a different context much more difficult.
o If the program must be modified, global dependencies increase the likelihood of introducing bugs. Moreover, introducing local changes require an understanding of the entire program.
o If a global variable gets an incorrect value, the entire program must be searched to determine where the error occurs; there is no localization.
o Recursion is more difficult to get right when the function makes use of a global variable.
From Brian Button :
1) 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. The urge to create something as a global to avoid passing it around is a smell in your design; it is not a feature of globals/singletons. If you examine your design more closely, you can almost always come up with a design that it is better and does not have to pass around tramp data to every object and method.
2) Singletons allow you to limit creation of your objects.
This is true, but now you are mixing two different responsibilities into the same class, which is a violation of the Single Responsibility Principle. A class should not care whether or not it is a singleton. It should be concerned with its business responsibilities only. If you want to limit the ability to instantiate some class, create a factory or builder object that encapsulates creation, and in there, limit creation as you wish. Now the responsibilities of creation are partitioned away from the responsibilities of the business entity.
3) Singletons promote tight coupling between classes
One of the underlying properties that makes code testable is that it is loosely coupled to its surroundings. This property allows you to substitute alternate implementations for collaborators during testing to achieve specific testing goals (think mock objects). Singletons tightly couple you to the exact type of the singleton object, removing the opportunity to use polymorphism to substitute an alternative. A better alternative, as discussed in the first point above, is to alter your design to allow you to pass references to objects to your classes and methods, which will reduce the coupling issues described above.
4) Singletons carry state with them that last as long as the program lasts
Persistent state is the enemy of unit testing. One of the things that makes unit testing effective is that each test has to be independent of all the others. If this is not true, then the order in which the tests run affects the outcome of the tests. This can lead to cases where tests fail when they shouldn’t, and even worse, it can lead to tests that pass just because of the order in which they were run. This can hide bugs and is evil. Avoiding static variables is a good way to prevent state from being carried from test to test. Singletons, by their very nature, depend on an instance that is held in a static variable. This is an invitation for test-dependence. Avoid this by passing references to objects to your classes and methods.
Enough for now
-Chris
Comment on this post below
You must be logged in to post a comment.
You can leave a response, or trackback from your own site.
