Product Site

5.4.19. Singleton Class (Metaclass)

The Singleton class is a metaclass (a subclass of the ooRexx metaclass Class) which can be used for any ooRexx class, if the programmer wishes only a single instance of a class to be created. In this case the class directive needs to denote Singleton in its METACLASS option.

This class is defined as a MXIN class.
Table 5.54. Singleton Class
Object
Methods inherited from the Object class
Class (Metaclass)
Methods inherited from the Class class
Singleton
new (Class Method)

Example 5.312. Employing the Singleton (meta)class

The following program defines a class TEST which makes sure that each instance has a unique number in its instance attribute nr. The TESTSINGLETON subclass uses the METACLASS Singleton option to make sure that it only creates a single instance, a singleton. The program will loop over the classes TEST and TESTSINGLETON, creates three instances of each and displays the value of the instance attribute nr and the identityHash value of each instance, which uniquely identifies each each instance of a class (cf. the MAKESTRING definition).
#!/usr/bin/env rexx
do clz over .test, .testSingleton   -- iterate over the two classes
   rounds=3
   say "creating" rounds "objects of type:" clz
   do i=1 to rounds
      say "   round #" i":" clz~new -- create new instance
   end
   say
end

/* ========================================================================= */
/** This Test class counts the number of instances that get created for it.  */
::class Test
/* ------------- class method and class attribute definitions -------------- */
::method init class  -- class constructor
  expose counter
  counter=0          -- make sure attribute is initialized to 0

::attribute counter get private class  -- getter method that increases counter
  expose counter     -- access attribute
  counter+=1         -- increase counter by 1
  return counter     -- return new counter value
/* ------------- instance method and instance attribute definitions -------- */
::attribute nr get   -- getter method

::method init        -- constructor that sets the value of attribute nr
  expose nr          -- expose attribute
  nr=self~class~counter -- new instance: fetch new counter from class and save it

::method makestring  -- a string representation of the object
  expose nr          -- expose attribute
                     -- return a string representation
  return "a" self~class~id"[nr="nr",identityHash="self~identityHash"]"

/* ========================================================================= */
/** This class makes sure that only a single instance of it gets created by
*   using Singleton as its metaclass.
*/
::class TestSingleton subclass Test metaclass Singleton

Output of running the above program (the hash values may differ on each run):
creating 3 objects of type: The TEST class
   round # 1: a TEST[nr=1,identityHash=-49085937]
   round # 2: a TEST[nr=2,identityHash=-49089489]
   round # 3: a TEST[nr=3,identityHash=-49093009]

creating 3 objects of type: The TESTSINGLETON class
   round # 1: a TESTSINGLETON[nr=1,identityHash=-49114993]
   round # 2: a TESTSINGLETON[nr=1,identityHash=-49114993]
   round # 3: a TESTSINGLETON[nr=1,identityHash=-49114993]

As can be seen from the output there are three distinct instances of the class TEST, however the three instances of the class TESTSINGLETON are identical (cf. the values of nr and identityHash).