Tag Archives: GoF

RaiiCap pattern: Injected Singleton alternative for C++

The Singleton design pattern is a so called creational pattern from the venerable GoF design patterns book. While this book is often seen as something of a software engineering Bible, the Singleton pattern I dare say (at the risk of being stoned to dead by GoF bigots) is one that , while being widely used and being immensely popular in software design, is in fact a very controversial pattern. A design pattern that I would want to refer to as an anti-pattern. So what is this Singleton pattern meant for? The GoF book states that a singleton is intended for when you aim to :

“Ensure a class only has one instance, and provide a global access point to it.”

No wait, “Ensure a class only has one instance” I could get into why you may wish for such a thing, butprovide a global access point to it” ? There are basically a few situations where providing global access to something isn’t an extremely bad idea.

  1. If its a constant.
  2. If it is a free standing function that does in no way use static mutables.
  3. A combination of one and two.

In any other conceivable scenario, global access is a terrible idea. It leads to tight coupling, to excess authority and knowledge, hard to test code, code that is impossible to reason about with respect to security properties like integrity and confidentiality, etc, etc.

So if we agree that having global access to a singleton, at least for any singleton that could not just as well have been implemented as a free standing function that accesses no static mutables, is a very bad idea, we can look at what we could do to provide for a useful pattern that aims to provide a way to accommodate “Ensure a class only has one instance”, while at all cost avoid the  “provide a global access point to it” part.

Well lets take a step back once more. There are two questions we need to ask about our problem before we set out to fix it. “Why would we want to assure that a class has only one instance of it”, and “Why would we need any design pattern to do that?” . The answer to the first question could be abstracted to : “There is a single shared resource that we need to manage.”, When you look at how singletons are used, you often see singletons managing a small pool of resources. So we could probably rephrase this to: “There is a scarce shared resource that we need to manage.”. 

So now we have the problem clear, its a resource management issue really. We have a scarce resource from what a substantial portion is acquired at class construction time (or in the GoF Singleton pattern,  lazily, but this is hardly an essential property that the Singleton strives to accomplish). So what we basically don’t want, if we have a large code base with many people working on it, that a developer would look at our class and think : “hey that looks about right, lets instantiate one of those over here”.

So basically what we need to stop this from happening is to find a way to limit access to the constructional patterns for creating instances of a resource management class.

To summarize my reasoning thusfar: We have reduced :

“Ensure a class only has one instance, and provide a global access point to it.”

to

“Ensure a class only has one instance”

that in turn we have expanded to the larger:

“Limit access to the constructional patterns  of a resource management class”

So lets see if we can device a new pattern for accomplishing this goal. I shall look at this from C++, as I feel I’ve solved this problem with a few C++ specific constructs and idioms. Solving the same problem with a pattern suitable for other languages is something I must currently leave as an exercise for the reader.

In C++, the base pattern for resource management is called RAII. I’m not going to rehash RAII here, but basicly it can be described as a ‘Constructor Aquires, Destructor releases, single responsibility’ pattern. Given that we identified our Singleton problem as being a resource management problem, any alternative to the Singleton problem in C++ should thus IMO basically rely on RAII as its basis.

So whats the problem with RAII that keeps us from using it as Singleton alternative already? The problem is that in most cases a RAII object that claims a substantial portion of a sparse resource can be constructed from anywhere within the code-base. There is nothing about a constructor other than maybe its constructor arguments that keeps you from instantiating an object from any place where you may like to do so, and there is nothing about the interface of a RAII class that should prompt the always in a hurry maintenance programmer to consider he/she may be depleting a resource or may be breaking the resource its access model by instantiating one more object.

As you might know from previous blog posts, I’m a big fan of capability based systems, and although C++ is about the language most removed from capability secure languages that one can get, and C++ by not being memory safe could by definition never have true capabilities, this should not keep us from using a capability like object in solving our problem. That is, we are not protecting our constructor from anything needing real capabilities here. We just want to make the in a hurry maintenance programmer think twice before claiming a scarce resource.  So lets just call these capability like objects for C++ RAIICaps, as they will be used in combination with RAII classes and are rather capability like in their nature.  So what would a RAIICap look like? Consider the following simple C++ template:

template <typename T>
class raiicap {
  public:
    friend int main(int,char **);
  private:
    raiicap(){}
};

Now within our RAII class we shall define our constructor as:

class raiiclass;
class raiiclass {
  private:
    ..
  public:
    raiiclass(raiicap<raiiclass> const &);
    ..
};

So what does this template do? Basically not much, it has an empty constructor nothing more, but this empty constructor is private, what keeps it from being instantiated in the normal way. C++ however has the friend keyword that can be used to give a befriended class or function access to the private parts of a class or object. The raiicap has no private member variables, but as its constructor is defined private, only its friends can instantiate it. The above defines the programs main  as friend. This means that only main can instantiate raiicaps, that it can than delegate to other parts of the program. Given that the RAII class requires a raiicap<raiiclass> reference as constructor parameter, this simple pattern effectively limits the access to the constructor of our RAII classes.

In main, this could look something like:

int main(int,char **) {
  raiicap<Foo> foo_raii_cap;
  Bar bar(foo_raii_cap);
  Baz baz();
  ..
  bar.bla();
  baz.bla();
  ..
}

In the above,  main instantiates a raiicap for Foo and constructor injects this raiicap into a new Bar object bar. The bar object now has the capability to create Foo objects. It might further delegate this capability, but this will need to be done explicitly. The also instantiated baz object does not get a raiicap to Foo and thus will have no ability to access to Foo’s constructor.

I think the above shows that, at least in C++, simple alternatives to the GoF Singleton pattern exist, at least for that part of the singletons intend that wasn’t a real bad idea to begin with. I’m pretty sure that similar patterns should be possible in other programming languages also. The most important thing to realize is that singletons in fact are a resource management pattern, and that for managing access to allocation of scarce resources, its a pattern that is both horrible and that, as shown above,  has alternatives that don’t have the same horrible side-effects.

Advertisements