Singleton

  • Object Creational Pattern

GoF definition (p. 127):

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

Sometimes a design calls for only one instance of a class. Rather than pollute the namespace with a globally scoped instance, use the singleton pattern to enforce single instance requirement.


Examples

Ruby

require 'singleton'

class Logger
  include Singleton # ruby includes a library for this pattern
  attr_reader :logs

  def initialize
    @logs = {}
  end

  def log(message)
    @logs[Time.now] = message
  end
end

Implimentation

my_logger = Logger.new # throws error

my_logger = Logger.instance # This returns the single instance

my_logger.log("Hello, world")
p my_logger.logs

PHP

<?php
class Singleton
{
    /**
     * @var Singleton The reference to *Singleton* instance of this class
     */
    private static $instance;

    /**
     * Returns the *Singleton* instance of this class.
     *
     * @return Singleton The *Singleton* instance.
     */
    public static function getInstance()
    {
        if (null === static::$instance) {
            static::$instance = new static();
        }

        return static::$instance;
    }

    /**
     * Protected constructor to prevent creating a new instance of the
     * *Singleton* via the `new` operator from outside of this class.
     */
    protected function __construct()
    {
    }

    /**
     * Private clone method to prevent cloning of the instance of the
     * *Singleton* instance.
     *
     * @return void
     */
    private function __clone()
    {
    }

    /**
     * Private unserialize method to prevent unserializing of the *Singleton*
     * instance.
     *
     * @return void
     */
    private function __wakeup()
    {
    }
}

class SingletonChild extends Singleton
{
}

$obj = Singleton::getInstance();
var_dump($obj === Singleton::getInstance());             // bool(true)

$anotherObj = SingletonChild::getInstance();
var_dump($anotherObj === Singleton::getInstance());      // bool(false)

var_dump($anotherObj === SingletonChild::getInstance()); // bool(true)

The code above implements the singleton pattern using a static variable and the static creation method getInstance(). Note the following:

The constructor construct() is declared as protected to prevent creating a new instance outside of the class via the new operator. The magic method clone() is declared as private to prevent cloning of an instance of the class via the clone operator. The magic method __wakeup() is declared as private to prevent unserializing of an instance of the class via the global function unserialize() . A new instance is created via late static binding in the static creation method getInstance() with the keyword static. This allows the subclassing of the class Singleton in the example. The singleton pattern is useful when we need to make sure we only have a single instance of a class for the entire request lifecycle in a web application. This typically occurs when we have global objects (such as a Configuration class) or a shared resource (such as an event queue).

You should be wary when using the singleton pattern, as by its very nature it introduces global state into your application, reducing testability. In most cases, dependency injection can (and should) be used in place of a singleton class. Using dependency injection means that we do not introduce unnecessary coupling into the design of our application, as the object using the shared or global resource requires no knowledge of a concretely defined class.


References

results matching ""

    No results matching ""