Singleton (ontwerppatroon)

Uit Wikipedia, de vrije encyclopedie
Ga naar: navigatie, zoeken

Singleton is een ontwerppatroon om het aantal objecten van een bepaalde klasse tot één te beperken. Met dit ontwerppatroon is het mogelijk om de toegang tot bepaalde systeembronnen altijd via één object te laten gaan.

Een toepassing van de singleton is bijvoorbeeld het maken van unieke identificatienummers binnen een programma. Om er altijd zeker van te zijn dat elk identificatienummer uniek is, is het handig om dit door één enkel object te laten genereren. Dit is dan een singleton.

Een singleton wordt gemaakt door een klasse te definiëren met een methode die een nieuw object aanmaakt als het nog niet bestaat en een bestaand object teruggeeft als er al wel een dergelijk object bestaat.

Klassediagram[bewerken]

Singleton UML class diagram.svg

Keerzijde van Singleton[bewerken]

Singleton is een controversieel ontwerppatroon. Singleton is eigenlijk tegengesteld aan de principes van het object-georiënteerd programmeren. Singletons introduceren binnen een programma een enkele globale instantie van een klasse in plaats van verscheidene instanties van een klasse daar waar nodig. Dit doorbreekt het patroon van een object-georiënteerd ontwerp en kan een stap terug betekenen naar het imperatief programmeren.

Bovendien moet in veel talen de Singleton zo geïmplementeerd worden dat het moeilijk of zelfs onmogelijk is om via overerving aanpassingen aan de Singleton-klasse te maken. In het bovenstaande voorbeeld is de Singleton uitgevoerd met behulp van statische methoden. In Java is het bijvoorbeeld erg moeilijk om via overerving het gedrag van een statische methode aan te passen. Het 'doorboort' de object-georiënteerde ontwerpprincipes.

Bij een verkeerd gebruik kunnen met een Singleton vaak heel makkelijk geheugenlekken geïntroduceed worden. Dit kan door onnodig beslag leggen van geheugen als hij niet gebruikt wordt en niet opgeruimd kan worden. Ook kunnen er geheugenproblemen ontstaan in talen als C++ waarin een component een Singleton kan verwijderen die nog elders in gebruik is. Bovendien kan in gedistribueerde programma's zonder voorzorgsmaatregelen een Singleton verscheidene malen geïnstantieerd worden en dus uiteindelijk geen Singleton zijn.

Voorbeelden[bewerken]

Java[bewerken]

Een voorbeeld in Java:

public class Singleton {
    private static Singleton _instance = null;
 
    // Private constructor vervangt de standaard public constructor 
    private Singleton () {}
 
    //gesynchroniseerde creator om multi-threading-problemen te voorkomen
    //nog een controle om te voorkomen dat er meer dan een object wordt geïnstantieerd
    private synchronized static void createInstance () {
        if (_instance == null) _instance = new Singleton ();
    }
 
    public static Singleton getInstance () {
        if (_instance == null) createInstance ();
        return _instance;
    }
}

C#[bewerken]

Een voorbeeld in C#:

public class Singleton {
    // Thread-safe oplossing om slechts één instantie aan te maken.
    private static Singleton _instance = new Singleton ();
 
    // Private constructor om te voorkomen dat anderen een instantie kunnen aanmaken.
    private Singleton () { }
 
    // Via een static read-only property kan de instantie benaderd worden.
    public static Singleton Instance {
        get {
            return _instance;
        }
    }
}

C# (met generics)[bewerken]

Een thread-safe voorbeeld met een luie initialisatie.

/// <summary>
/// Generic class implements singleton pattern.
/// </summary>
/// <typeparam name="T">
/// Reference type. Important: Must have private constructor (not public).
/// </typeparam>
public class Singleton<T> where T : class
{
    protected Singleton () { }
 
    public static T Instance {
      get { return SingletonCreator.instance; }
    }
 
    class SingletonCreator
    {
        // static SingletonCreator() { } redundant as it is created by the compiler automatically
        internal static readonly T instance = typeof(T).InvokeMember(typeof(T).Name,
                           BindingFlags.CreateInstance |
                           BindingFlags.Instance |
                           BindingFlags.NonPublic,
                           null, null, null) as T;
    }
}

PHP 5[bewerken]

Singleton-patroon in PHP 5:

class Singleton {
    // object instance
    private static $instance;
 
    private function __construct() {}
    private function __clone() {}
 
    public static function getInstance() {
        if (!Singleton::$instance instanceof self) {
            Singleton::$instance = new self();
        }
        return Singleton::$instance;
    }
}

Ruby[bewerken]

Singleton-patroon in Ruby

require 'singleton'
 
class Singleton
    include Singleton
end

Scala[bewerken]

Singleton-patroon in Scala is een taalelement.

object Singleton
 
// Gebruik:
val singleton = Singleton

Thread safety gegarandeerd

C++[bewerken]

Singleton-patroon in C++

.h

class CSingleton {
    protected: 
             CSingleton();
    public:
             virtual ~CSingleton();
             static CSingleton* Instance();
    private:
             static CSingleton* m_pSingleton;
};

.cpp

 
//Definieer static om linkererrors te voorkomen
CSingleton* CSingleton::m_pSingleton = NULL;
 
CSingleton::CSingleton() { }
CSingleton::~CSingleton() { }
 
CSingleton* CSingleton::Instance()
{
    if(m_pSingleton == NULL)
       m_pSingleton = new CSingleton;
 
    return m_pSingleton;
}
Bronnen, noten en/of referenties