because Hindley-Milner rocks
To me, singleton is a four letter word. I understand they have their places but I find them few and far between. Thread pools, Socket pools, DB Connection pools and memory pools I can understand. They’re representing expensive or limited resources which the program might not have control over. Abstract factories, Factory objects, or Builders it’s semantics (of which I’ll not choose singletons.) Anything else like Config file objects or UI components and make me want to scream.
Today, during design discussions one engineer remarked that Singletons can’t hurt a single-threaded application. With things run sequentially, what’s the worry? Coming from first hand knowledge, tons. I had already lost the battle for immutable objects in our data connection classes from the start. It seemed we’d be using a mutable Singleton instead. Frustrating but not worth a 3 hour debate.
Coming back to the question of what harm can a mutable Singleton do in a single-threaded solution let me turn to an application I had the misfortune of fixing just the other week. The singleton in question represented the contents of a configuration file. There were default initialization values hard-coded in case either the config “went missing” or if certain optional fields were not present.
The original code had worked flawlessly because it had been written by one developer. When it came time to update the code, the next developer had mistakenly accessed functionality within other classes that relied upon the Singleton before the config had been read. From the outward appearances, that developer had very little reason to suspect the code in question even used any of the Singleton’s fields. He would have needed to go down several classes deep in the class nesting to see it.
Therein lies the problem with Singletons, by their very nature they hide state transitions. The summoner of the Singleton has neither knowledge if he is the first to summon nor if another has changed the state prior to summoning. Management of state becomes a burdensome proposition which must be made a top priority. As global variables, their use in even single-threaded applications imposes some of the same themes encountered in multi-threaded applications.
So let me write out another blog entry, joining the chorus of developers railing against the proliferation of Singletons in code the world over. Singletons, those four-letter expletives that continue to haunt my days. Curse you. Aaargh!