Singleton: Alternative to the Anti-Pattern

There are valid reasons for using a Singleton in your design - these reasons, however, are rare enough that many developers can avoid them entirely and still have a full career. If you find yourself using Singletons often, you're doing something wrong.

I made quite a splash when I advocated the use of Singletons in WordPress development.

I still stand by Singletons as a valid design pattern – and my method for making them testable in PHP.  At the same time, I recognize that Singletons are considered an anti-pattern for a specific reason.

If you don’t, then what follows is absolutely important for helping you understand why not to use Singletons.

If you already agree, skip the next part and move on to the resolution.

The Dangers of Singletons

The entire point of a Singleton is to prevent multiple instances of your object from living together in the same context.  This is a valid concern when your object represents, say, a PHP header collection, the current request, or the final response being sent to the client.

Single-instantiation, however, breaks the ability to test the object as, even in your test suite, you can only create one copy of the object.[ref]There are ways around this by using, for example, process isolation.[/ref]  If you’re building a well-covered application – and you are building a well-covered application, right? – this particular limitation of Singletons will give you a headache.

Singletons are also inherently inextensible – you cannot subclass a Singleton.  As your application grows, however, the need to subclass an object can and will come up.

Take my example above – that a Singleton could represent the response object being sent to the client.  What if you decide to extend a JSON API for your application?  The easiest way is to extend your general response object to create a JSON-specific one; if it started as a Singleton, however, you can’t.

There are valid reasons for using a Singleton in your design – these reasons, however, are rare enough that many developers can avoid them entirely and still have a full career.  If you find yourself using Singletons often, you’re doing something wrong.

An Alternative

In the world of WordPress, developers will often use a Singleton to wrap some sort of god object[ref]The god object is another dangerous anti-pattern that I will address in the future.[/ref] that wires in all of their actions and filters.  The justification behind this pattern is extensibility – other developers will need an easy way to get a reference to your original instance so they can remove, reorder, or otherwise manipulate your chosen hooks.

Kudos to developers wanting to make their code extensible.

Boo to developers using Singletons to do so.

Instead, developers should investigate and utilize a variation on the “factory method pattern.”  Thanks to static method variables in PHP, it’s fairly straight-forward to expose a uniform access method on your object that always returns the same instance of that object or creates one if it doesn’t exist.

For example:

class Example {
public function __construct() {
add_filter( 'the_content', array( $this, 'the_content' ) );
}

public function the_content( $content ) {
return $content;
}

public function do_something() { }

public static function factory() {
static $instance = false;
if ( ! $instance ) {
$instance = new self;
}

return $instance;
}
}

// In your code elsewhere:
Example::factory()->do_something();

remove_filter( 'the_content', array( Example::factory(), 'the_content' ) );

Just be sure that, in your code that [cci]include()[/cci]s this file, you call [cci]Example::factory()[/cci] rather than instantiate the object directly. Instantiating the object will not populate the factory’s internal instance container – production code should avoid direct instantiation and always defer to the factory.

To be even safer, you could move any hook wiring to a method other than the constructor – one that you invoke directly. Then subsequent, accidental instantiations won’t double-bind events.

How This Solves the Singleton Problem

Singletons are used in WordPress to provide universal access to an instantiated object without needing to pass a variable from one function to another.  The pattern above does the same.

Singletons prevent an object from being instantiated more than once, breaking the ability of unit tests to isolate state from one another.  The pattern above allows tests to create as many copies as they need by directly firing the constructor and bypassing the factory method.

Singletons prevent object sub-classing for new method implementations.  The pattern above allows subclassing both instance methods and the factory method being used.

Moving Forward

If you’re using Singletons in your WordPress code, I strongly recommend you reconsider.  The above example is but one way to achieve the same universal access and functional single-instantiation Singletons provide, but without crippling your code’s testability or extensibility.

If you aren’t convinced factory methods are better than Singleton accessors, I’d be interested to know why.