An Elegant Way To Implement The Singleton Pattern
Introduction
I have been trying to find an elegant way to implement the singleton pattern for ages. The main window of a GUI application is a classic example. Now finally I came up with a way I am happy with. Specifically I wanted a way to create an object naturally in an application, and then for the object to make itself available as a shared instance to the rest of the application without first having to call the object from a once function. The latter method I would call an "unnatural way", for want of a better term.
The Solution
The problem is solved by introducing two classes: EL_SHARED_SINGLETONS and EL_SINGLETON. They are used in the following way:
Make a call to routine {EL_SINGLETON}.put_singleton
from within the class you wish to share as a global instance:
class MY_CLASS
inherit
EL_SHARED_SINGLETONS
feature {NONE} -- Initialization
make
do
put_singleton (Current)
..
end
then define the shared once function as follows:
deferred class SHARED_GLOBAL_INSTANCE
inherit
EL_ANY_SHARED
feature {NONE} -- Constants
Global_instance: MY_CLASS
local
l: EL_SINGLETON [MY_CLASS]
once ("PROCESS")
create l
Result := l.singleton
end
end
Now just make sure to call the make
routine of MY_CLASS before any calls to Global_instance
. But in case you call Global_instance
to soon, there is a contract to warn you, and it will also throw a helpful exception even when assertions are omitted from the build.
Class EL_ANY_SHARED by the way, is just a convenience class for easy inheritance. Routines copy, default_create, is_equal
and out
are left undefined.