Classic Singleton

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?

Responsibility Design

Good software objects have clearly defined responsibilities. The class side of an object has two basic contracts with the rest of your application…

  1. To deliver properly formed instances of itself.
  2. 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)

Extensibility

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
instanceVariableNames: ''
classVariableNames: 'Instance'
poolDictionaries: ''
category: 'WidgetsRUs-Model'

Then I create a class method #getInstance which returns the contents of “Instance” (lazy initializing if necessary)

class>>#getInstance
^Instance ifNil: [Instance := self basicNew ].

Finally I stop #new from returning another instance of my class

class>>#new
^self shouldNotImplement

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.

Explore posts in the same categories: Design Patterns, Objects, Smalltalk

4 Comments on “Classic Singleton”

  1. Damien Cassou Says:

    Hi,

    really good explanation.

    I often implement your #getInstance lazy initialization as “super new” instead of “self basicNew”. What is the best solution ? I prefer “super new” currently because I can access it and #new is the real method for creating new instances. For me, #basicNew is an implementation detail. But if I subclass my singleton, I can’t access “super new” anymore, so I’m stuck.

    Can you explain me what are the pros/cons of your solution ?

    Thank you


  2. Hi Damien

    By making explicit calls to super you can cause you code to be dependent on what the super class is doing e.g. if the #new in you superclass (or one of its ancestors) returns “super new initialize” then in a subclass you override #new to return “super new initialize” then you get the initialize sent to your new subclass instance twice.

    Any method that begins “basic” should not be overridden and therefore its effects can be more predictable – “self basicNew initialize” would guarantee that the initialize method only gets called once and you are not subject to the quirks of the superclass implementation.

  3. Ben R Says:

    Alan! You can be googled remarkably easily. Have not got a clue what your on about here but was intruiged to see if I could find your blog. Nice work!


  4. Hi Ben

    Better watch what I say (or go via a pseudonym) 🙂


Leave a reply to Damien Cassou Cancel reply