Singletons In D
March 3rd, 2007 | by Aldacron |The intent of the Singleton pattern is described by the Gang of Four thusly:
Ensure a class only has one instance, and provide a global point of access to it.
Singletons are ubiquitous in object oriented programming. They are also, I feel, abused and overused. But, I’m not going to go into a philosophical rant on how I think the pattern should and shouldn’t be used. My goal today is just to show a few simple ways to implement the Singleton pattern in D.
First, we’ll start with an implementation based on the first technique described by the GoF:
class MySingleton
{
public:
static MySingleton instance()
{
if(_instance is null) _instance = new MySingleton;
return _instance;
}private:
this() {}static MySingleton _instance;
}
This implementation instantiates the single object instance the first time the instance method is called. There are a couple of key points to note here that apply to all Singletons.
First, there is only one constructor and it is private. Exposing any constructors would defeat the purpose of having a Singleton by allowing users to instantiate instances of the object themselves. Simply omitting a constructor will not work either, since D automatically creates a public default constructor when none is declared. So all Singleton implementations should declare a private constructor. In most languages, this ensures that only the class can instantiate itself. In D, however, private class members are private to the module in which the class is declared and not to the class itself. As a rule of thumb, it’s probably a good idea to define Singletons in their own modules when using the implementation above. If you do mix them with other code, be sure not to instantiate the Singleton more than once. You can protect yourself against this, though (see below).
The second point of note is that the single class instance and its accessor method are both static. This combined with the private constructor ensures that the class has complete control over the instantiation of the single instance (with the caveat about module scope mentioned above).
In Java, singleton instances are sometimes declared public rather than private, like this:
class JavaSingleton {
public static final instance = new JavaSingleton();private JavaSingleton() {}
}
The final keyword ensures that the instance is only instantiated once. Attempts to instantiate it again will result in compilation errors. D includes a final attribute as well, but it is not same as Java’s. In Java, final can be applied to a class declaration to prevent subclassing, or to a member variable declaration to ensure it is only initialized once, or to a method to prevent it from being overridden by a subclass. In D, as far as I can tell, it only can be applied to methods to prevent them from being overridden by subclasses — final classes can be subclassed (declaring a class final in D just means that none of its methods can be overridden) and final members can be reinitialized. So if you are tempted to use the same technique in D, you can’t use the final keyword to do so. You’ll have to use const instead.
If you declare the static object instance to be const, you must use a static class constructor to initialize it:
class MySingleton2
{
public:
static const MySingleton2 instance;private:
this() {}static this() { instance = new MySingleton2; }
}
It is possible to initialize static class members at the point of declaration, but the initialization value must be a constant (i.e. static int x = 10;). The new statement is not a constant value and therefore must be implemented in a static class constructor.
Static constructors are run by D during application initialization (though the D bootstrap code must be called manually when using a WinMain method on the Windows platform). Because the single object instance is initialized in a static class constructor, it is guaranteed to be initialized before the instance method is called. Furthermore, because the instance member is static const it can only be initialized in a static class constructor. Any attempt to initialize it outside of the static class constructor will result in a compiler error. You could make the instance member private and give it an accessor method, but there’s really no reason to do so as long as it is static const — the value of instance cannot be changed after it is initialized. If you make it private and remove the const, it will be vulnerable at module scope as mentioned above.
In D, I would suggest that you prefer this technique unless there is a reason to use lazy instantiation, in which case you should go with the first. Additionally, both implementations can be templated.
A template version of the first implementation:
class Singleton(T)
{
public:
static T instance()
{
if(_instance is null) _instance = new T;
return _instance;
}private:
this() {}static T _instance;
}class TMySingleton : Singleton!(TMySingleton)
{
}
And of the second:
class Singleton2(T)
{
public:
static const T instance;private:
this() {}static this() { instance = new T; }
}class TMySingleton2 : Singleton!(TMySingleton2)
{
}
These are 4 basic D Singleton implementations that should cover 99% of the use cases you will have for the pattern. When and how you use them and which version(s) you use I leave entirely up to you. What these implementations do not provide is a way to replace the single object instance with that of a subclass at initialization. Maybe I’ll look at that another day (meaning, I haven’t even attempted to implement it yet).
I’ve provided a source module which gives a simple example of using each of the above implementations. Compile it if you want, but you can just run it as a script:
dmd -run singleton.d
If you are using GDC, replace dmd with gdmd.
Technorati Tags: D Programming Language, Singletons, Gang of Four, Design Patterns, templates, programming
By Henning Hasemann on Mar 9, 2007
Thanks
By Matthias Thurau on Jun 30, 2007
Hi, nice Tutorials. The Problem i found with the Template versions is, that you can t add the Singleton Template from another Module. So you have to have the Singleton Template in every Module you want to have a SingletonClass (I think)
I made something with Mixins today:
template Singleton() {
public:
static typeof(this) getInstance() {
if (_instance is null) _instance = new typeof(this)();
return _instance;
};
private:
this() { writefln(”Singleton Constructor”); };
static typeof(this) _instance;
};
class ResourceLoader {
mixin Singleton!();
int some_more_stuff;
private:
this() { writefln(”ResourceLoader Constructor”); };
}
bye
By Stephane Wirtel on Jul 7, 2007
Hi all,
Thanks for this tutorial about the Singleton pattern, but can I have the same problem with a multithreaded environment ? about the Double-Checked Locking ?
bye
By Aldacron on Jul 7, 2007
@Matthias:
The Problem i found with the Template versions is, that you can t add the Singleton Template from another Module. So you have to have the Singleton Template in every Module you want to have a SingletonClass (I think)
That shouldn’t be happening. I’ve not been able to reproduce it myself. As long as you import the module that declares the singleton instance, you should be able to use it anywhere. It might break on Windows when compiled into a static library (a known template problem on that platform) but other than that it should work fine.
@Stephane:
can I have the same problem with a multithreaded environment ? about the Double-Checked Locking ?
The version that uses a static constructor should be thread-safe, as far as accessing the singleton instance is concerned. No need for any locking or other synchronization measures.