design-patternssingletonsmalltalkseaside

uniqueInstance on Seaside Smalltalk


I'm trying to implement the Singleton pattern on Seaside. Here is my code:

        uniqueInstance
            uniqueInstance ifNil: [ uniqueInstance := self createInstance].
            ^ uniqueInstance

    createInstance
        ^ self basicNew

initialize
    users:= OrderedCollection new.

On the instance side I have users that is the instance variable. When I call Application uniqueInstance initialize works. When I inspect the users variable, it said "Identity Set" instead of an OrderedCollection.

Can anybody give me a solution to my mistake?


Solution

  • Based on a (Pharo) mailing list discussion regarding singletons I wrote about some variations some time ago https://www.peteruhnak.com/blog/2015/12/06/singleton-variations/ .

    But the gist of the singleton is:

    1. (usually) block MyThing class>>new
      • because it is a singleton
    2. call super new or self basicNew initialize when creating the instance
      • this is to go around the blocked new; if your dialect doesn't call initialize automatically then use the latter form
    3. (optionally) add MyThing class>>reset to nil the instance
      • for convenience mostly (with <script: 'self reset'> pragma can be made even better)

    So in your case it can be something like this:

    Users class>>uniqueInstance
        ^ uniqueInstance ifNil: [ uniqueInstance := super new ]
    
    Users class>>new
        self error: 'Users is a singleton -- send uniqueInstance instead'
    
    Users>>initialize
        users:= OrderedCollection new
    

    And if you are in Pharo, feel free the explore the existing implementations

    MessageBrowser browse: (#uniqueInstance implementors select: #isMetaSide).
    MessageBrowser browse: (#default implementors select: #isMetaSide).
    MessageBrowser browse: (#current implementors select: #isMetaSide).