Sorry Singleton I don’t love you anymore.
Q: Where have all the global variables gone?
A: They became singletons.
Recently I am having the privilege of being involved in an EhP5 “upgrade” project at a leading international entertainment and media company. Given that 6 or so years ago I was putting in an ITS version of ESS at this same company (which has survived pretty much unchanged until now) it was probably high time that they did consider “upgrading”.
As many will know, one of the main “attractions” in the HCM side of EhP5 or Business Suite Innovations 2010 is the change over from a Web Dynpro Java (WDJ) Employee Self Service (ESS) to a Web Dynpro ABAP (WDA) solution. This gives us some real flexibility in enhancing the standard services to meet the specific needs of each implementation. Whilst at a code level SAP have mainly just replaced the WDJ service with WDA ones which do pretty much the same thing, there have been a few changes.
One of the most significant changes has been the switch over from a function group/function module based coding approach (necessitated by using RFC enabled function modules to interact with WDJ) to a more class based approach. (Some of the functionality was already very OO based, but it’s even more so now.)
OO so good.
I have to say I applaud this change. Using classes and a more object orientated approach is a good thing. For a start, type checking is much better, and as of 7.02 I can build my beloved Law of Demeter defying train-wrecks. There are so many benefits to designing in an OO sense, that I’m not going to try to cover them all here. Let’s just pretend to agree that OO programming is a good thing. If you don’t agree, that’s fine, I accept that you may have a point in one microscopically small instance that exists for something approaching Plank time.
But there is one little change that has crept up on me and I am seeing more and more of it in standard SAP code. This is the singleton class pattern. The basic idea of a singleton is that it is an object instance that should exist only once in memory. So for those things that should only every have one instance at a time. You know, like global variables… Perhaps this is some internal SAP thought – in a recent discussion with Thomas Jung he has some very favourable remarks about the use of singletons as a memory efficient means of sharing data between WDA components.
In a world of change, some things are constant?
Sometimes SAP developers are accused of moving slowly, and I can understand why. When you look at the features of the ABAP language that are only just starting to get explored by developers and some of the developers out there who still have no idea about what OO is about, but yet have little difficulty in finding work, it makes me sad. Still you think we could turn this to our advantage, as we’d have plenty of time to learn from the non-SAP world about good and bad practice?
I recently sent a less than 140 character message to a really clever man I know (recent winner of SAP Tech Ed Las Vegas Demo Jam, “the real one” according to Ed Herrmann) :
” alisdair73: A Singleton class pattern is effectively a complex global variable. Global variables are bad. Discuss… “
Discussion ensued and Alisdair Templeton set me on the path to understanding a little more about singletons. It was only the start of a discovery about how the rest of the world hates the singleton pattern. Thoughts vary from Singletons being evil, to stupid, to depressing. It seems hardly anyone has a good thing to say about them.
“Singletons are Evil”
Why is this? I’ll try to summarise for the sake of all those of us out there who look at SAP standard coding and use it as the basis for our next project. (Perhaps I’m learning, perhaps not.)
Firstly a singleton can be a type of global variable – why don’t we like global variables? The problem with global variables is that you never know what bit of code is going to modify it. You cannot code a unit test for your own code without first setting the state of an external value and then hoping like mad it doesn’t change. A singleton has global state, which not only means that my code has to run in circles to handle what it could be doing, it also could be changed in the middle of my code and I’d never know about it. Imagine the fun you’d have debugging that one!
Secondly, you cannot have, by very definition, two singleton instances. It is a very, very, rare case that you will only ever want to have one instance. If you build it so you can only have one, there will come a time in the future when you will want to have more and you will be stuffed (technical term oft used in Australia.)
And in particular:
Getting back to my EhP5 ESS implementation, the one particularly irksome singleton that has arrived on the scene is to do with the currently selected employee. This is used throughout the code. I can select an employee and start a new application, and that application can find out what employee I selected – wonderful. But I could also change the selection, what happens then? Well there is some logic to apply a “handle” to the singleton to ensure you get the one you want… But it’s still a singleton. If I call some method in my code, there is certainly no guarantee that the globally accessible state of the singleton will not have changed. Goodbye to the idea of test driven development… It will be a challenge when I’m asked to display two employees side by side in the same application using “standard” code.
Why do this to me?
Given that the singleton is required to be able to construct itself from a given database handle (as a new application could fire off in a different app server) why not just make it a non-singleton and pass it around? Perhaps there are reasons that are deeper than I understand from my brief exposure to the code. Using this particular pattern seems to occur more in the EhP5 code (especially in sharing data between WDA components and/or WDA assistance classes). Even though it is being used more a brief web search reveals that it doesn’t just seem to be me that is adverse to this pattern for use in any circumstances.
To summarise (again).
- Just because it says it’s a pattern and because it is supposedly OO does not mean it is good.
If you are tempted to use a singleton, stop! Think. Would you code the same thing with global variables? If you would, well, nothing I’m going to say would stop you, go ahead, because we all want ” Singletons over carefully reasoned, loosely coupled design” don’t we? (I hope not!) If the term “global variable” actually does give you a little concern, please, please reconsider that singleton pattern you were thinking of using.
Disclaimer: you shouldn’t listen to anything I say. It’s likely to be wrong, misleading, confusing and unrepresentative, and in no way reflects the opinions of my employer or most sane people. Any perception of a deeper understanding is probably just an optical illusion and you should be very careful in interpreting it otherwise.
P.S. all the little drawings of singleton code men (yes that is what they are supposed to be, that’s why there is a 1 on his/her front) are badly drawn by me 🙂 Hope you like them.