"There can be only ONE!"
Singleton
In traditional Cobol programming all programs are singletons. Well, this a sort of joke, but pretty much basically a procedural program cannot be instantiated. In the other hand OO Cobol classes are by nature just a model to create one, or two, or one billion objects. So, what if our application needs to deal with a single instance of a given class, ensuring that only one instance would exist at anytime? Here comes the GOF Singleton pattern!
UML diagram

As we can see in the diagram above, the class constructor is private, so no one can instantiate that class direclty. To get an instance we need to call the method "GetInstance". That method would check if the private attribute called "instance" is null. If so, the method would then call the class constructor NEW (which is visible for it), set the class attribute "instance" with the new instance, and return the instance to the caller. Next time that method is called it would return the already created class instance.
Too confuse? I thought so :)
Step-by-step
- Program (or some object) invokes Singleton.GetInstance static method
- GetInstance checks if private attribute contains null or a valid Singleton instance
- If null, GetInstance calls the class constructor "NEW" to create a new instance
- The new instance is stored in the private attribute "instance" and returned
- If not null, the instance already created would be returned
- There can be only ONE ;)
OO Cobol code
1: CLASS-ID. Singleton AS "CoolThings.Singleton".
2: *> Static data and methods
3: static.
4: data division.
5: working-storage section.
6: 01 instance usage object reference SINGLETON is private.
7:
8: procedure division.
9: method-id. GetInstance AS "GetInstance".
10: data division.
11: linkage section.
12: 01 localSingleton usage object reference SINGLETON.
13:
14: procedure division returning localSingleton.
15: if (instance equal null) then
16: invoke Singleton "NEW" returning localSingleton
17: set instance to localSingleton
18: else
19: set localSingleton to instance
20: end-if
21:
22: end method GetInstance.
23: end static.
24: *> Instance's data and methods
25: object.
26: environment division.
27: data division.
28: working-storage section.
29: 01 counter pic s9(04) value zeros.
30:
31: procedure division.
32: method-id. NEW is private.
33: data division.
34: procedure division.
35: move zeros to counter.
36:
37: end method NEW.
38:
39: method-id. GetCounter as "GetCounter".
40: data division.
41: linkage section.
42: 01 localCounter pic s9(04).
43:
44: procedure division returning localCounter.
45: add 1 to counter.
46:
47: move counter to localCounter.
48:
49: end method GetCounter.
50:
51: end object.
52: END CLASS Singleton.
Testing our singleton
program-id. usingSingleton as "usingSingleton".
environment division.
configuration section.
repository.
class ClassSingleton as "CoolThings.Singleton".
data division.
working-storage section.
01 singletonInstance1 usage object reference ClassSingleton.
01 singletonInstance2 usage object reference ClassSingleton.
procedure division.
invoke ClassSingleton "GetInstance" returning singletonInstance1
invoke ClassSingleton "GetInstance" returning singletonInstance2
invoke ClassSingleton "GetInstance" returning singletonInstance3
display singletonInstance1::"GetCounter"
display singletonInstance2::"GetCounter"
display singletonInstance3::"GetCounter"
Running the code above we would see the following output in the console window.
0001
0002
0003
In our example, the GetCounter method actually updates the counter and return its new value. First call to GetInstance forces the Singleton to be created and our counter to be initialized with zeros, incremented by 1 and returned. Subsequent calls just increase counter value. Notice that we are not creating the Singleton instance in the code above. That's impossible because the constructor (NEW) is private. All that we can do is to request the instance using the "GetInstance" method.
Where to use Singletons?
You name it! A class that controls the number of database connections? A round robin class that forward the request to a server in a cluster? Overall settings for the application? Possibilities are endless!
Download the source
http://cobolrocks.codeplex.com/SourceControl/changeset/view/36237#533800
Some references in the web
http://www.dofactory.com/Patterns/PatternSingleton.aspx#UML
http://en.wikipedia.org/wiki/Singleton_pattern