Primus2: Singleton Design Pattern


This code has been deprecated and moved.  It is now found in the Phabstractic Library.  You can find more information at the project page, as well as view the current blog entry.

I’m proud to announce the implementation of the Singleton Pattern in primus2\falcraft.

The Singleton Pattern

To quote Wikipedia:

In software engineering, the singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects. The term comes from the mathematical concept of a singleton.

Also, you might also check out this article for more information, particularly in applications (which I’ll reiterate here), as well as this article.  For something more PHP specific, there’s also this article.

As stated in the articles, in summary, many individuals see the Singleton Pattern as an anti-pattern.  That is, a tool used to make code less optimal.  The biggest drawback I can see is in testing in particular.  As Mr. MacGregor wrote in the above article, dependency injection is often used in php frameworks to make them more modular and easier to test.  When you have to provide an instance of an object for another object, then you know exactly what the dependencies are for that object when it comes time to write tests for it.

However, a class may use an undocumented singleton previously defined in the script.  When you don’t know the internals of the code, this dependency becomes the problem of a global variable: its a hidden dependency.

On top of that for testing purposes, a singleton will stick around for each unit test.  This means if one test function uses a singleton, and then another test function uses code that uses the same singleton, whatever happened in the previous test function remains in the singleton.  This will produce unintentional results.

Singletons are not entirely without merit however.  There are domains in which a singleton provides a convenient and modular answer.  As points out, there may only be need for one window manager, one file system (like the OS X Finder), one print spool, one logging mechanism, one configuration resource, one database access point, etc.  I think these are proper uses of a singleton pattern.  I’m a little less on using a singleton as a shared resource among parts of the program.

I think that if you are going to use a singleton for a shared resource, it should be implemented as one giant global repository, such as a Registry pattern.  This collects and provides access to other singletons and, although discouraged, global objects and variables.

This is the plan to be implemented in Primus, There may be a singleton or single instance of a class, such as an autoloader.  This will be registered with the global registry so that the program can use one singleton to access it.

In this particular implementation we used the concept of traits in PHP.  A trait is a bit like a mix-in, somewhat like an interface but not quite.  Traits and interfaces should definitely not be confused.  A trait encapsulates common functionality between classes without using inheritance.  An interface only provides a guarantee that functionality exists in some form.  The falcraft\patterns\Singleton trait provides an instantiate() method that creates the singleton.  Optionally, arguments may be passed on the first instantiation (such as configuration information).  You override the init() method to parse the arguments given at first instantiation, as the __construct() method is made private (to prevent instantiation through the ‘new’ PHP keyword).  In order to test if you can pass arguments, or if a singleton has been instantiated you can use the static function hardened().

Here is the original code:

Note that the __construct() method is declared as private.  As written, this is to prevent the ability to instantiate a singleton object using the ‘new’ keyword.  If you could use ‘new’ then multiple copies of the singleton may then exist.  However, this means that that an object using the Singleton  trait cannot declare its own __construct() method.  In order to ‘construct’ the singleton with initialization (including arguments) use the protected init() method.  In fact, this method is defined as abstract in the trait, making it necessary to declare this method in any implementations.

View the Source on GitHub

photo credit: XMAS200720D5018II004 via photopin (license)


I'm just a wunk, trying to enjoy life. I am a cofounder of http// and I like computers, code, creativity, and friends.

You may also like...

Leave a Reply

%d bloggers like this: