February is nearly out and I haven’t posted for a few weeks so I thought I’d just throw in my thoughts on the use and misuse of Singletons! Many of my colleagues working in Java pepper their code with static methods and use them as placeholders for pure function calls. Some would argue that the language encourages this.
I’ve also seen the same thing in Smalltalk code – since the class side only exists once in the image it is in effect a Singleton and therefore we can use this to our advantage and write class methods to achieve the Singleton effect. So if you want to create a WidgetFactory as a Singleton you can simply add class methods to WidgetFactory that return widgets for you (e.g. #getWidget:). But just because you can doesn’t mean you should!
So why not?
Good software objects have clearly defined responsibilities. The class side of an object has two basic contracts with the rest of your application…
- To deliver properly formed instances of itself.
- To manage state that is shared across all instances of the class
The class side should not be responsible for delivering instances of other classes. The class side of a WidgetFactory can return an instance of a WidgetFactory but it should not return a Widget. It’s not its responsibility.
Object Domain Model
It sounds obvious but an object software is made up of objects. Classes are not part of your domain model. They are meta objects that describe the shape and contents of your domain objects. If there is a need for a Singleton to perform a task like “create new Widgets based on some criteria” then this should be the responsibility of a WidgetFactory or the WidgetFactory (if you only want one of them in your image) but it is not the responsibility of the “WidgetFactory Class”. There is no such thing as a “WidgetFactory Class” in your domain model (unless of course your domain is meta programming)
As you design you can often be pretty sure that you want the WidgetFactory to be a Singleton (i.e. there will only ever be one WidgetFactory in the entire image). But what happens down the line when you discover the need for a second WidgetFactory (like the first but maybe implementing a slightly different WidgetContruction strategy). If all of your Widget creational methods (e.g. #getWidget:) are implemented as instance methods you can easily allow your application to create a second WidgetFactory which all your code will work with unaltered.
If you implemented #getWidget: as a class method on WidgetFactory you’ve now got a refactoring job to do. You can’t have a second WidgetFactory class – Smalltalk won’t let you and what’s more all your clients of #getWidget: are calling the class side. Ouch!
So how so you code a Singleton in Smalltalk?
Well first you define a class variable to hold the single instance – (I usually name this “Instance”)
Object subclass: #WidgetFactory
Then I create a class method #getInstance which returns the contents of “Instance” (lazy initializing if necessary)
^Instance ifNil: [Instance := self basicNew ].
Finally I stop #new from returning another instance of my class
Some people are tempted to make class>>#new return Instance although I prefer not to as this sets a false expectation on the reader of any client code that a new instance is being returned.