Home / Singletons: Two ways about it

Singletons: Two ways about it

Singletons are one of many design patterns that developers employ to solve common problems. In part two of this three-part series, we are going to study two of the different ways to create singletons.

This post is at a high intermediate level as it relies on knowledge of some high-level object-oriented concepts such as static properties and methods. Although this post has examples in PHP, the concepts it describes apply to all object-oriented programming languages.

If you haven’t already, check out the first part of this series: Singletons: What are they and When to use them.

The next post in this series hasn’t been written yet, feel free to follow us on Twitter, or just bookmark this page and check back in a week.

There are two ways?

Well, there are probably many more. However, in my experience, I have found two solid ways of ‘implementing’ Singletons that work across any object-oriented programming language: Object Singletons and Static Classes.

Object Singletons: The classic Singleton

If you google ‘singleton php’ all the results that actually load, and aren’t videos, will show you the PHP code to build an object singleton. Many of the textbooks I have read, across many languages, present this as the defacto singleton. And for good reason, it’s versatile, doesn’t take much code to set up, and quite easy to understand, even for beginners.

However, recently I have started to do singletons slightly differently:

Static Classes: Almost a Singleton

Well yes, I’ll be the first to admit that using purely static class is NOT a singleton.

However, many of the problems that singletons are used to solve, actually have slightly cleaner solutions if a static class is used instead. So why don’t we kick off the comparison by looking at some code!

Whats the difference when I use them

We are following on from the example global variable from singletons part 1. It’s an object that stores some information about the current web request.

For code examples ‘RequestInfo’ is our classic singleton, and ‘RequestData’ is a static class that does the same thing.

Calling a function from a singleton

Classic Singleton:

$request_info = RequestInfo::GetInstance();
echo $request_info->GetConnectionAge();
// Or, for a 1 liner
echo RequestInfo::GetInstance()->GetConnectionAge();

Static Class:

echo RequestData::GetConnectionAge();

The code is slightly cleaner when using a Static Class.

Setting a simple variable

Classic Singleton:

$request_info = RequestInfo::GetInstance();
$request_info->$connection_name = “Connection: $connection_id”;
// Or, for a 1 liner
RequestInfo::GetInstance()->$connection_name = “Connection: $connection_id”;

Static Class:

RequestData::$connection_name = “Connection: $connection_id”;

Again, there is slightly less code required for the static class.

Before I bore you to death with almost identical code examples, let’s just spot the pattern. For static class implementations, there is no need to call GetInstance(), (note: in some examples this function is called Instance(), or Factory()). This simply cleans the code up a little.

Only a little, however, since with a Singleton, you can call GetInstance() once at the top of your code, and operate on that variable for the rest of the time.

So static classes give cleaner code? At a cost.

Unfortunately, it’s not all fun and games.

Remember 32 seconds ago when I said how great not having to call GetInstance() is? Well, this may be a (small) problem.

The joy of GetInstance, is that it allows us to set up the singleton if it has never been set up before. This guard allows us to know that the singleton is properly initialised.

Static classes have no such built in security. However, this can be circumvented easily by including an __init() function in your static class, that you call right after the class is declared!

The other issue is more elegantly described in code:

Classic Singleton:

print_r(RequestInfo::GetInstance());

Static Class:

// There is no way of passing a static class to a function that expects an object!

By definition, static classes are not objects. So passing them around like objects is impossible. This can be slightly limiting, however, I have never found this case to be an issue in practice!

When should I use one over the other?

Well, the only hard rule is with the limitations of static classes:

If you need to pass your global object around like a regular object, you have to use a Singleton!

Other than this, I can only give recommendations:

I use static classes if:

  • The structure I am implementing only has functions
  • The structure I am implementing is an interface/abstraction upon an API (Such as a mySQL Server)
  • I am simply grouping some functions/variables together

I use Singletons if:

  • I need to pass it around as an object
  • It has a more complicated internal structure and is better thought about as an object
  • When I say ‘shall we use a static class’ to my team they say ‘a Whatty Whatnow?’, but when I say ‘how about a Singleton’ they say ‘that’s a great plan’

This last point is maybe the most important, particularly if you have a beginner on the team. Although it is often appropriate to teach them what a static class is (maybe send them to this blog post) it’s sometimes more important to maintain code understandably!

If you are with me so far that Singletons and Static Classes are useful global structures, check back for part three of this series, where we will look at implementing these two structures (prepare for a lot of code).