Smart Tech for a better Web

The Singleton issue - an everlasting discussion

von

Today it looks that everybody needs an very extreme opinion in each technical topic. I mean, Windows is evil, OS X too, but Linux is uncomfortable and Unix is dead. JavaScript is just a toy, without JavaScript you don't have a professional website. Java is slowest, Java is coolest and so on and so on. Finally: Singletons are evil. By the way, sometimes several people say that using design patterns destroy the ability of thinking yourself.

In fact, I strongly believe that every concept has benefits and drawbacks. Should I use Singleton? It depends.

So what's wrong with that pattern?

Some people claim that the Singleton pattern is a sign of bad software design. They say the Singleton can be used as some kind of global variable. Well, that's true, sometimes. But the Singleton can be used otherwise than a global variable holder. Actually you have to differ between your programming language before thinking about a good or bad usage of the Singleton Pattern.

How to implement the Singleton pattern in PHP

PHP is a scripting language, it's actions are performed by an interpreter. It doesn't support multiple threads like Java or Ruby does. This is very important later. But first, lets create a singleton in PHP.

class MySingleton {
    private static $instance;
    private function __construct() {}
    public static function getInstance() {
        if (self::instance == null) {
            self::instance = new MySingleton();
        }
        return self::instance;
    }
}

How does this work? You create a static variable in a class. If one calls getInstance() for the first time, a new object is created and stored in the static variable. If you call the method again, you'll get exactly the same instance you created with the first call. This object - since it is static - will stay until your script has ended and the complete request is processed. You see, why the singleton has it's name. It's only one object created and used for all the time.

And to keep this behaviour, you just have to put your constructor private - nobody else than your getInstance method should be allowed to create this object.

How to implement a Singleton with Java

Now you have to think about some more issues. Since Java supports multi-threading you have to think about more than just creating the object and returning it. First, we'll see how a pure PHP programmer would create the singleton with Java syntax.

public class MySingleton {
    private static MySingleton instance;
    // Again - just MySingleton is allowed to construct this object
    private MySingleton() {}
    public static getInstance() {
        if(instance == null) {
            instance = new MySingleton();
        }
        return instance;
    }
}

OK, now think about two threads which call getInstance() at the same time, and imagine nobody has done so before. Both threads would enter getInstance(). Chances are good that Java helps you even with multiple processors (it should do, cause Suns Sales Managers sell Java as a simple to use language ;-)). In that case, one thread would go on to create the MySingleton object, while the other one will jump over it and return the instance.

You have to ask the question, does this really work? Cause at which point of time is instance not longer null? The answer is, if you create the object headers, the instance variable is not longer null. That means, that a second thread could overtake thread one and work on an instance which is not really created (just the have of it)! Something unexpected will occur and even if your customer will claim about an error, you probably will never have the chance to find it.

So what now? We have to make sure that:

  1. two threads are not creating a MySingleton object at the same time
  2. one thread doesn't work on the object while it is still under construction

Some programmers start something like this:

public class MySingleton {
    private static MySingleton instance;
    public static getInstance() {
        if(instance == null) {
            synchronized(this) {
                if(instance == null) {
                    instance = new MySingleton();
                }
            }
        }
        return instance;
    }
}

Please note the synchronized block above. It keeps care that only one thread can execute the code for creation at one time.

Is this the solution? No. Even in that case it can happen that Thread 1 locks everything correctly for creating the object. But if Thread 2 comes at a bad time, it will ask the outer instance == null check and again it could return an unfinished object. The synchronized block just helps with one problem.

Actually there is only one 100% solution. Create the necessary object while class loading.

public class MySingleton {
    private static MySingleton instance = new MySingleton();
    public static getInstance() {
        return instance;
    }
}

This is a solution PHP programmers cannot have since PHP doesn't support to create objects like this. But for the Java programmer its the only way to make object creation work. And yes, sometimes its not possible to go this way. But that's another story.

Singleton Lifetime

You should know about another difference between Java and PHP Singletons. In Java, the static keywords makes the variable available at a class level, not at object level. This means it follows you as long as the JVM is alive - from program start to program end, and in case of an enterprise or an EAI server, this can take a long, long time.

For a PHP program it's the same - from program start to program end. But in PHP words this means the time when an HTTP request arrives and script execution begins till the end of the script has been reached. After a request, the singleton is gone, dead, and you'll have to create it again, with the next request.

In human words, this means that a Java singleton probably lives for days, weeks or even months and the PHP singleton just for less milliseconds.

The Benefits of Singleton

Well, benefit is: you have to create only one object of an class and can use it over and over again. This is cool, since creating an object takes usually a long time in the interpreter or in the virtual machine. Cause of this, old programmers often say object orientation is slow. Meanwhile everything is faster and in most cases you don't have to care bout this anymore.

And this is where critic starts: people say, you could misuse the Singleton as some kind of global variable store. This comes often from PHP programmers, who think about that code:

class MySingleton {
    ...
    public $bla = "blubber";
    public static function getInstance() {
        ...
    }
}

In this case, you can have the variable $bla available all over your code. Just do a:

MySingleton::getInstance()->$bla;

Is this good? No. Of course not. If you just want to store something, go ahead, use $GLOBALS or a similar global available variable. Same goes to Java. There are no global fields, but you can create some similar with System properties.

But Singleton will have more the worth if the singleton object has some methods you can operate on. Imagine that singleton object tries to reload a configuration.

class MySingleton {
    ...
    public $bla = "blubber";
    public function loadConfiguration() {
        // code to load xml file
        $this->bla = getValueFromXML();
    }
    ...
}

This would make it possible to reload the config at runtime. Even date formatting etc. would be possible at runtime.

Basically said, an object which provides methods is worth something. It's not to bad to do so. But a more cool benefit is if you have a stateless singleton.

class MySingleton {
    ...
    public function doSomething($bla) {
        $bla = $bla / 2;
        return $bla;
    }
    ...
}

Imagine doSomething() does some complex things with $bla. You don't need to store the result in the MySingleton object. It will returned. Since there are no object variables available, this object is stateless. And there is really no need to create multiple objects just to perform some operations on $bla.

But why should one consider to create an object if he can do this in a static way, you ask. Static access to methods is not very flexible. Think on AOP, where objects wrap other objects and prevent you from calling a method directly. This wouldn't work. That's just one example. There are others: maybe you want to choose at runtime, which implementation you use to create this task. In a static context you would have to change your implementation, in an object context you could use a factory and a strategy pattern to switch. This is way more flexible.

Drawbacks of the Singleton pattern

Yes, of course there are several. Think on the global variable thing. It's true, imagine you have one thousand of Singletons, all keeping care of their own little states, read within the application from a million of places. Not very good. Especially with PHP you cannot easily find out where those variables are called. In Java you have some good shortcuts in your IDE.

But we know now, that a Singleton is meant for reducing object creation time and not for state sharing. Next drawback is more significant, since the first one is a mistake just inexperienced programmers do.

Problem is, if you create a Singleton it will stay one forever. If you need to make multiple objects of your class, you have to write code for this. In small projects this is not such a big issue, but in a 100.000 lines of code project it is. There are other patterns like Prototype or Factory which could be useful suddenly and we would have to write code. This is a risk.

The solution is to create this Singleton not by code like we did above. Use a framework for creating your objects. In PHP you PIWI and the BeanFactory at your side, which helps you with constructing singletons (and injects the objects in other objects - Dependency Injection, see the previous article).

In Java you can use Spring for this. Spring is the big inspiration source for PIWI (regarding object creation and dependency injection) and widely used. Besides Spring there is Google Guice and PicoContainer too, which provide similar stuff.

Finally

There is no need to say Singleton is good or bad. It's neither. It's just a pattern. A Singleton is just as evil as you misuse it, and just as glorious as you identify it as fitting pattern to a specific problem.

In my projects I use a Singletons sometimes for configuration. I don't think it's bad behaviour. If I don't have one thousand of this object in my System, it's OK. More often Singletons are used as some kind of worker classes, just here for doing complex stuff with storing a state. They help me not to waste memory. And due Singletons are objects I easily can extends them via aspect oriented programming - perfect!

Tags: #Design Patterns #Java #PHP

Newsletter

ABMELDEN

BLOG-POST TEILEN

When you load these comments, you'll be connected to Disqus. Privacy Statement.