Singleton (ontwerppatroon)
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 | brontekst bewerken]Keerzijde van Singleton
[bewerken | brontekst 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ïntroduceerd 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 | brontekst bewerken]Java
[bewerken | brontekst 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 | brontekst 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;
}
}
}
PHP 5
[bewerken | brontekst 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 | brontekst bewerken]Singleton-patroon in Ruby
require 'singleton'
class Singleton
include Singleton
end
Scala
[bewerken | brontekst bewerken]Singleton-patroon in Scala is een taalelement.
object Singleton {
val pi = 3.14
var teller = 0
}
Ook hier met Scala thread safety gegarandeerd, bovendien kunnen er "companion" klassen gemaakt worden.
C++
[bewerken | brontekst 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;
}
- Singleton Considered Stupid - Steve Yegge, 3 september 2004