Chris Donnan : Programming - Brooklyn Style
software, trading, family, fun
Posted programming on Monday, May 29th, 2006.
I keep finding applications, frameworks, and general methods that have ‘Singleton-itis’ or ‘Static everything’. Ugh!
A static reference is a concrete class dependency
Concrete class dependencies give you transitive dependencies
ex:
-NiceNewClass_X has zero depends to start
-We decide it could reuse stuff in StaticHelperClass_Y
-StaticHelperClass_Y has depends on 9 classes
-So - NiceNewClass_X now has all of the depends that StaticHelperClass_Y has (10 depends now all told)
The better situation would be if NiceNewClass_X depended on interface IHelperClass_Y. Then this class would have 1 dependency - on an interface (and any types that it needs to take as arguments, return types (hopefully abstractions as well).
Static-singletons - vs container managed singletons
Lets differentiate clearly. Singletons that are coded as static-singletons are one thing. You code it as a singleton - and you access it via a static accessor. This is a singleton that gives you a concrete class dependency. A container managed singleton is only a singleton via configuration.
IoC
Inversion of control enables this - ‘newing’ in your class has the same coupling and transitive dependency problem that a static class has. It is a concrete class dependency. So - we elect to depend on interfaces or abstract classes if need be and allow those abstractions to be passed in via constructor or via setter. This minimizes our direct class dependencies. I NO LONGER have to know about how to build my children, and I do not have the cascading dependencies on my children’s children’s children etc.
This does come at a price - you kill encapsulation - sort of, unless you defer to a container to be the assembler. This is what Spring and all the other lightweight containers are for.
Statics are Globals
Globals - we all know they are bad. Statics are globals! c’mon now - admit it
Statics are not testable
You cannot test singletons effectively. You also cannot mock out static references when you are testing other classes that depend on static-singletons. This is one of the worst parts - you cannot separate and test! So - static-singletons mess your testing methods up.
Separation of interface from implementation
Static singletons FORCE you to NOT separate interface from implementation. YOU CANNOT PROGRAM TO AN INTERFACE when using a static-singleton. This is a GREAT reason to use container managed singletons (as opposed to static-singletons)- you CAN substitute implementation. Static singletons are a violation of the ISP - interface segregation principal. YOU MUST SEPERATE INTERFACE FROM IMPLEMENTATION. Statics KILL this!!! Since you cannot substitute implementation - this is - IMHO a violation of the OCP - open closed principal. Your code should be ‘open for extension -but closed for modification’. Normally if you want to vary behavior - you pass in a different dependency. With a static-singleton - you cannot pass in varying dependencies. That being said - now if you want to vary the behavior of a static-singleton - you must OPEN THE CODE FILE AND CHANGE IT - thus violating the OCP.
When are statics OK?
I DO LIKE private static methods - just to illustrate that they are side effect free - no class member variables changed.
When used correctly - statics are fine - I just believe that static methods are OK - static fields are bad. I do NOT want my static methods to effect class state. Static factories are a prime example of static singletons that are alright. This is tricky - as I do like static ‘utility’ type functionality. I think that statics can be used - but I think that you must REALLY understand when NOT to use them 1st - then you can use your best judgment as you go.
Use a static-singleton when there REALLY IS PHYSICALLY ONLY ONE - like a COM port or something. CODE it as a singleton because there is PHYSICALLY only one. In many cases - people code singletons because ‘it seems like there should only need ever be one’ not because there REALLY IS or REALLY MUST BE only one. The truth is that often a pool of objects is better than a singleton in some cases. Sometimes you reach that conclusion later and YOU ARE ALREADY DEPENDENT on SINGLETONS STATICALLY across reams of code. THIS IS BAD. This is why singletons are bad - you are VERY bound to them and changing your mind later is hard.
The singleton-ness of objects
I believe the singleton-ness or non-singleton-ness of an object should be deferred to the container (eg; spring, etc). It is nice to be able to defer that decision and you are not bound to things being either singleton via discrete implementation. In any case - defer to the container! When you do this - you can decide that things should or should not be singletons as their usage pattern emerges.
WinForms and a static Main Form
I will always blabber about this one… One place I do NOT like it is especially when used in Win Forms apps for a ‘main form’ that is statically available. I cannot say why I hate it so much - but it just irks me and smells bad. I have heard the argument that it is convenient and therefore good. I just disagree - don’t do it
These main forms are VERY stateful. You do not want to have a static-singleton FULL of state etc. Also - what happens when you want to use this ‘main form’ in a new MDI type version of your application. This main form -as it turns out is not REALLY the main form -now it is just a ‘type’ of form in your application - now you have to go - de-singleton it - touching ALL references to it - and seeing how to pass along the dependencies now… UGH!
One singleton to rule them all
I have heard Spring referred to as ‘one singleton to rule them all’. This is true to a degree. Spring must 1st be accessed as a static singleton - to get the app context. I try to do this ONE time in the startup file and THAT IS ALL. From there - you can just stop statically referring to the app context. In any case - the ‘container’ really is one singleton to own the singleton-ness (note- they are not static now - just singletons by configuration). So - the container really is the only true singleton that does rule them all.
Singletons != statics … not necessarilyÂ
So - you do not have to code everything as a singleton!!!! This is excess code that does not NEED to be in your software. Make your own plain-old-objects - and defer their singleton-ness to the container. You CAN have singletons that are that way via configuration - not implementation. Static-singletons are what you want to avoid.
De-Singleton-ing, or static-singleton purging
I have been on many missions to slay static-singletons. Take it upon yourself to do this - go kill static-singletons. Find the 100000 references to your static-singleton. Replace them with some interface reference. Figure out a concrete class that implements that interface or interfaces. Figure out how to get references to your dependent classes (hopefully via spring or the like).
Closing thoughts
I had a collegue that used to say to people in interviews - “Static-singletons are evil can you tell me why I might say that ?”. Good question
I guess my thoughts on static-singletons are clear
My Best;
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.















