Liste von Singleton-Implementierungen
Dies ist eine Liste von Implementierungen des Entwurfsmusters Singleton in unterschiedlichen Programmiersprachen.
Implementierung in ActionScript
[Bearbeiten | Quelltext bearbeiten]Ab Version 2
[Bearbeiten | Quelltext bearbeiten](ohne Schutz vor direkter Instanziierung)
class Singleton {
private static var _instance:SingletonClass;
private function Singleton() {
}
public static function get instance():Singleton {
if(!_instance) _instance = new Singleton();
return _instance;
}
public function doSomething():Void {
}
}
/* @use:
Singleton.instance.doSomething();
*/
Ab Version 3
[Bearbeiten | Quelltext bearbeiten]In ActionScript 3 können Konstruktoren nicht als privat deklariert werden. Eine mögliche Lösung besteht darin, mittels einer privaten Klasse sicherzustellen, dass der Konstruktor nur von innerhalb der Singletonklasse aufgerufen werden kann:
package {
public class Singleton {
private static var _instance:Singleton = null;
public function Singleton(se:SingletonEnforcer) {
if(se === null) {
throw new Error('Singleton kann nicht direkt erstellt werden. Verwende Singleton.instance');
}
}
public static function get instance():Singleton {
if(_instance === null) {
_instance = new Singleton(new SingletonEnforcer() );
}
return _instance;
}
}
}
internal class SingletonEnforcer {}
Implementierung in C#
[Bearbeiten | Quelltext bearbeiten]Allgemein ohne Threadsicherheit
[Bearbeiten | Quelltext bearbeiten] // Nur zur Veranschaulichung – bitte nicht verwenden!
class Singleton
{
private Singleton() { }
private static Singleton instance = null;
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
Verwendung:
Singleton a = Singleton.Instance;
Singleton b = Singleton.Instance;
Assert.AreEqual(a,b);
Threadsicher
[Bearbeiten | Quelltext bearbeiten]Eine threadsichere Methode, entnommen aus dem MSDN-Magazin[1].
class Singleton
{
private Singleton() { /* ...hier optional Initialisierungscode... */ }
public static readonly Singleton Instance = new Singleton();
}
Verwendung:
Singleton a = Singleton.Instance;
Singleton b = Singleton.Instance;
Assert.AreEqual(a,b);
Das Singleton-Prinzip wird bei C# durch zwei Maßnahmen erreicht:
- Durch die Deklaration des Konstruktors als privat (
private Singleton(){}
) kann dieser von außerhalb der Klasse nicht mehr aufgerufen werden – das Erstellen des Objektes ist also nur noch von innerhalb der Klasse möglich. - Das statische öffentliche Feld Instance speichert und liefert schreibgeschützt Zugriff auf das einzige Objekt der Klasse.
- Wichtig
- Der Konstruktor wird von der CLR nicht automatisch beim Programmstart aufgerufen. Erst beim ersten Zugriff auf eine Klasse werden alle statischen Member der Klasse initialisiert – in diesem Fall die Instanziierung des einen Objektes. Wenn also nie auf diese Klasse zugegriffen wird, wird der Konstruktor auch niemals ausgeführt – und das Objekt wird nie erstellt. Dieser Effekt tritt auch dann noch ein, wenn die Klasse selbst als statisch deklariert wird.
Möchte man sichergehen, dass das Singleton-Objekt beim Programmstart erstellt wird, so muss man einen beliebigen Zugriff in das Hauptprogramm (public static void Main() { }
) einbauen.
Threadsicher mit doppelt überprüfter Sperrung
[Bearbeiten | Quelltext bearbeiten]Bei der doppelt überprüften Sperrung handelt es sich um ein Antimuster. Jedoch funktioniert diese Variante threadsicher und wird oft von unerfahrenen Entwicklern eingesetzt.
class Singleton
{
private Singleton() { }
private static volatile Singleton instance;
public static Singleton Instance
{
get
{
// DoubleLock
if (instance == null)
{
lock(_lock)
{
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
// Hilfsfeld für eine sichere Threadsynchronisierung
private static object _lock = new object();
}
Verwendung:
Singleton a = Singleton.Instance;
Singleton b = Singleton.Instance;
Assert.AreEqual(a,b);
Hinweise zum Code:
- Das private Hilfsobjekt
_lock
ist hier unbedingt notwendig. Die frühere gängige Methodelock(this){ … }
hat sich als unzureichend herausgestellt, weil fehlerhafter oder böswilliger Code durch den AufrufMonitor.Exit(Singleton);
die Threadsicherheit einfach aushebeln kann. - Double-Lock-Muster: Damit nach der Instanziierung des Objektes die bremsende Synchronisation per lock() wegfällt, wird dieselbe If-Abfrage zusätzlich vor dem Lock-Abschnitt eingesetzt.
- Das Schlüsselwort volatile bewirkt, dass die Instanz von mehreren Threads gleichzeitig bearbeitet werden kann.
Falls es keine konkreten Einwände gibt, dass das Singleton-Objekt auch schon früher instanziiert werden darf, ist der vorher beschriebene Code einfacher und schneller und daher in C# vorzuziehen.
Threadsicher mit Synchronisation
[Bearbeiten | Quelltext bearbeiten]Eine Umgehung des Double-Lock-Antimusters ist die Verwendung des MethodImpl
-Attributs um einen synchronisierten Methodenaufruf zu gewährleisten.[2] Dies entspricht dem Schlüsselwort synchronized
in Java.
class Singleton
{
private Singleton() { }
private static volatile Singleton instance;
public static Singleton Instance
{
[MethodImpl(MethodImplOptions.Synchronized)]
get
{
if (instance == null)
instance = new Singleton();
return instance;
}
}
}
Verwendung:
Singleton a = Singleton.Instance;
Singleton b = Singleton.Instance;
Assert.AreEqual(a,b);
Generisch
[Bearbeiten | Quelltext bearbeiten]Eine einfache generische Variante[3][4]
public class Singleton<T> where T : class, new()
{
private Singleton() { }
private class SingletonCreator
{
static SingletonCreator() { }
internal static readonly T instance = new T();
}
public static T Instance
{
get
{
return SingletonCreator.instance;
}
}
}
Bei dieser Variante kann das Delegat-Konstruktor-Handshake-Pattern eingesetzt werden um sicherzustellen, dass der öffentliche parameterfreie Konstruktor nur von der generischen Singleton-Klasse aufgerufen werden kann:
public class SomeSingleton
{
public SomeSingleton(Singleton<SomeSingleton> caller)
{
if (caller == null)
{
throw new Exception();
}
}
}
Alternativ kann System.Reflection
oder System.Diagnostics
verwendet werden um Informationen über die aufrufende Objekt zu erhalten. Hierzu muss das aufzurufende Objekt im Konstruktor übergeben und analysiert werden. Zudem wird dabei nicht die new()
-Bedingung erfüllt, weshalb das entsprechende Konstrukt entfernt werden muss.
Generisch mit statischer Fabrikmethode
[Bearbeiten | Quelltext bearbeiten]Bei dieser Variante wird eine statische Fabrikmethode verwendet um die Singleton-Instanz zu erzeugen.[5]
public class Singleton<T> where T : class
{
// Methode zur Erzeugung einer neuen Instanz, welche als Delegat übergeben wird
public delegate T CreateInstanceDelegate(Singleton<T> caller);
private static CreateInstanceDelegate CreateInstanceMethod { get; set; }
// Konstruktor
public Singleton(CreateInstanceDelegate createInstanceMethod)
{
if (CreateInstanceMethod == null) throw new ArgumentNullException();
CreateInstanceMethod = createInstanceMethod;
}
// Lock-Objekt für Threadsicherheit
static readonly object Padlock = new Object();
// Singleton-Instanz
private static T _instance = null;
public T Instance
{
get
{
lock (Padlock)
{
if (_instance == null)
_instance = CreateInstanceMethod(this);
return _instance;
}
}
}
}
Einsatz:
public sealed class SomeSingleton
{
public static SomeSingleton CreateInstance(Singleton<SomeSingleton> caller)
{
return (caller == null) ? null : new SomeSingleton();
}
private SomeSingleton() { }
}
Verwendung:
SomeSingleton a = new Singleton<SomeSingleton>(SomeSingleton.CreateInstance).Instance;
SomeSingleton b = new Singleton<SomeSingleton>(SomeSingleton.CreateInstance).Instance;
Assert.AreEqual(a,b);
Generisch, Abstrakt
[Bearbeiten | Quelltext bearbeiten]public abstract class Singleton<T> where T : Singleton<T>
{
private static T _instance;
protected static bool IsInitialised { get { return (_instance != null); } }
protected static T Instance { get { (IsInitialised) ? SingletonCreator.Instance : null; } }
protected Singleton() { }
protected static void Init(T newInstance)
{
if (newInstance == null) throw new ArgumentNullException();
_instance = newInstance;
}
// da C# keine abstrakten statischen Methoden erlaubt,
// wird die Erzeugung der Singleton-Instanz an diese Klasse weitergeleitet
private class SingletonCreator
{
static SingletonCreator() { }
internal static readonly T Instance = _instance;
}
}
Einsatz:
public sealed class SomeSingleton : Singleton<SomeSingleton>
{
public static SomeSingleton Instance
{
get
{
(IsInitialised) ? return UniqueInstance : Init(new SomeGenericSingleton());
}
}
private SomeSingleton() { }
}
Verwendung:
SomeSingleton a = SomeSingleton.Instance;
SomeSingleton b = SomeSingleton.Instance;
Assert.AreEqual(a,b);
Generisch, Abstrakt, Lazy
[Bearbeiten | Quelltext bearbeiten]Dies ist eine generische abstrakte Klasse die eine Singleton-Instanz lazy erzeugt.[6]
public abstract class Singleton<T> where T : class
{
// Lazy Instanziierung
private static readonly Lazy<T> _instance = new Lazy<T>( () => CreateSingletonInstance() );
public static T Instance
{
get
{
return _instance.Value;
}
}
private static T CreateSingletonInstance()
{
// Konstruktion des Singleton-Objekts
return Activator.CreateInstance(typeof(T), true) as T;
}
}
Einsatz:
class SomeSingleton : Singleton<SomeSingleton>
{
// öffentliche Felder und Methoden
public string SomeString {get; set; }
// Konstruktor muss private sein
private SomeSingleton()
{
}
}
Verwendung:
SomeSingleton a = SomeSingleton.Instance;
SomeSingleton b = SomeSingleton.Instance;
Assert.AreEqual(a,b);
Generisch mit Aufruf eines privaten Konstruktors über Reflexion
[Bearbeiten | Quelltext bearbeiten]Die folgende Variante ruft einen privaten Konstruktor über Reflexion auf:[7]
public class Singleton<T> where T : class
{
private Singleton() { }
private class SingletonCreator
{
static SingletonCreator() { Instance = CreateInstance(); }
private static T CreateInstance()
{
ConstructorInfo constructorInfo = typeof(T).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, Type.DefaultBinder, Type.EmptyTypes, null);
if (constructorInfo != null)
return constructorInfo.Invoke(null) as T;
else
return null; // oder: throw new InvalidOperationException("Should have a private parameterless constructor");
}
internal static readonly T Instance { get; private set; }
}
public static T Instance
{
get { return SingletonCreator.Instance; }
}
}
Einsatz:
public class SomeSingleton : Singleton<SomeSingleton>
{
private SomeSingleton() { }
}
Verwendung:
SomeSingleton a = SomeSingleton.Instance;
SomeSingleton b = SomeSingleton.Instance;
Assert.AreEqual(a,b);
Implementierung in C++
[Bearbeiten | Quelltext bearbeiten]Die Implementierung im Buch Entwurfsmuster ist nur für Single-Thread Programme geeignet. Bei Multi-Thread Programmen muss die get Methode durch ein Mutex geschützt werden. Diese C++11 Single-Thread Implementierung basiert auf der vor C++98 Implementierung im Buch Entwurfsmuster.[8]
#include <iostream>
class Singleton {
public:
// definiert eine Klassenoperation, die es Klienten ermöglicht, auf sein einziges Exemplar (Instanz) zuzugreifen.
static Singleton& get() {
// ist potentiell für die Erzeugung seines einzigen Exemplars zuständig.
if (nullptr == instance) instance = new Singleton;
return *instance;
}
Singleton(const Singleton&) = delete; // Dreierregel
Singleton& operator=(const Singleton&) = delete;
static void destruct() {
delete instance;
instance = nullptr;
}
// existierende Schnittstelle folgt hier
int getWert() {
return wert;
}
void setWert(int wert_) {
wert = wert_;
}
private:
Singleton() = default; // kein public Konstruktor
~Singleton() = default; // kein public Dekonstruktor
static Singleton* instance; // Deklaration Klassenvariable
int wert;
};
Singleton* Singleton::instance = nullptr; // Definition Klassenvariable
int main() {
Singleton::get().setWert(42);
std::cout << "wert=" << Singleton::get().getWert() << '\n';
Singleton::destruct();
}
Die Programmausgabe ist:
wert=42
Das Meyers Singleton[9] nutzt eine statische Variable in der Methode get. Deshalb gibt es keine destruct Methode. Die Programmausgabe ist wie oben.
#include <iostream>
class Singleton {
public:
static Singleton& get() {
static Singleton instance;
return instance;
}
int getWert() {
return wert;
}
void setWert(int wert_) {
wert = wert_;
}
private:
Singleton() = default;
~Singleton() = default;
int wert;
};
int main() {
Singleton::get().setWert(42);
std::cout << "wert=" << Singleton::get().getWert() << '\n';
}
Dritte Methode: Bietet eine Basisklasse, um auf einfachste Weise eine Klasse als Singleton auszuweisen.
template <class T_DERIVED>
class CSingleton
{
public:
static T_DERIVED& GetInstance()
{
static T_DERIVED oInstance ;
return oInstance ;
}
protected:
CSingleton(){}
private:
CSingleton( const CSingleton& ) ;
CSingleton& operator=( const CSingleton& ) {return *this;}
} ;
// Verwendung
class CMySingleton : public CSingleton< CMySingleton >
{
friend class CSingleton< CMySingleton >;
private:
CMySingleton(){}
//...
};
Implementierung in Delphi
[Bearbeiten | Quelltext bearbeiten]Implementierung ab Delphi 5
[Bearbeiten | Quelltext bearbeiten]unit Singleton;
interface
uses
Windows, Dialogs, Forms, sysutils;
type
TSingleton = class
protected
constructor CreateInstance;
class function AccessInstance(Request: Integer): TSingleton;
public
constructor Create;
destructor Destroy; override;
Procedure MyFoo();
class function Instance: TSingleton;
class procedure ReleaseInstance;
end;
implementation
//******************************************************************************
constructor TSingleton.Create;
begin
inherited Create;
raise Exception.CreateFmt('Access class %s through Instance only',
[ClassName]);
end;
//******************************************************************************
constructor TSingleton.CreateInstance;
begin
// Meine internen Dinge erzeugen
// ...
inherited Create;
end;
//******************************************************************************
destructor TSingleton.Destroy;
begin
// Meine internen Dinge freigeben
// ...
if AccessInstance(0) = Self then AccessInstance(2);
inherited Destroy;
end;
//******************************************************************************
class function TSingleton.AccessInstance(Request: Integer): TSingleton;
{$WRITEABLECONST ON}
const
FInstance: TSingleton = nil;
{$WRITEABLECONST OFF}
begin
case Request of
0 : ;
1 : if not Assigned(FInstance) then FInstance := CreateInstance;
2 : FInstance := nil;
else
raise Exception.CreateFmt('Illegal request %d in AccessInstance',
[Request]);
end;
Result := FInstance;
end;
//******************************************************************************
class function TSingleton.Instance: TSingleton;
begin
Result := AccessInstance(1);
end; // Instance
//******************************************************************************
class procedure TSingleton.ReleaseInstance;
begin
AccessInstance(0).Free;
end;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure TSingleton.MyFoo();
begin
// Mach was
end;
end.
Aufruf:
TSingleton.Instance.MyFoo();
Implementierung ab Delphi 2007
[Bearbeiten | Quelltext bearbeiten]unit Singleton;
interface
uses
SysUtils, Windows, Messages, Classes, Controls, StdCtrls, Forms, Dialogs;
type
TSingleton = class(TInterfacedObject)
private
class var
FInstance: TSingleton;
protected
constructor CreateInstance;
public
constructor Create(const Dummy:Integer = 0);
destructor Destroy; override;
Procedure MyFoo();
class function Instance: TSingleton;
class procedure ReleaseInstance;
end;
implementation
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
constructor TSingleton.Create(const Dummy:Integer = 0);
begin
inherited Create;
raise Exception.CreateFmt('Access class %s through Instance only',
[ClassName]);
end;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
destructor TSingleton.Destroy;
begin
// Meine internen Dinge freigeben
// ...
if FInstance = Self then FInstance := nil;
inherited Destroy;
end;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
constructor TSingleton.CreateInstance;
begin
// Meine internen Dinge initialisieren
// ...
end;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class function TSingleton.Instance: TSingleton;
begin
if FInstance = nil then
FInstance := CreateInstance;
Result := FInstance;
end;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class procedure TSingleton.ReleaseInstance;
begin
if FInstance <> nil then
FreeAndNil(FInstance);
end;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure TSingleton.MyFoo();
begin
// Mach was
end;
end.
Aufruf:
TSingleton.Instance.MyFoo();
Implementierung in Java
[Bearbeiten | Quelltext bearbeiten]Gemäß Joshua Bloch[10] ist die beste Art, ein Singleton in Java zu implementieren, die folgende:
public enum Singleton {
INSTANCE;
public void doSomething(){
//TODO
}
}
Verwendung:
Singleton.INSTANCE.doSomething()
Diese Art funktionierte ab Java Version 5, da erst mit dieser Version Enums eingeführt wurden.
Allgemein
[Bearbeiten | Quelltext bearbeiten]Die Erstellung des einmalig existierenden Objekts wird folgendermaßen erreicht:
- Der Konstruktor der Singleton-Klasse ist privat. So ist es von außen nicht möglich, ein weiteres Objekt dieser Klasse zu erzeugen.
- Als Ersatz wird eine neue Zugriffsmethode angelegt, die eine Referenz auf das einzige Objekt zurückgeben kann.
- Die Variable, in der das Objekt gespeichert wird, erhält den Modifikator „statisch“ (
static
). Sie ist außerdem synchronisiert, um die Sicherheit bei nebenläufiger Ausführung zu gewährleisten. In Java wird auch dabei das Objekt erst erzeugt, wenn es gebraucht wird.
public final class Singleton
{
/**
* privates Klassenattribut,
* wird beim erstmaligen Gebrauch (nicht beim Laden) der Klasse erzeugt
*/
private static Singleton instance;
/** Konstruktor ist privat, Klasse darf nicht von außen instanziiert werden. */
private Singleton() {}
/**
* Statische Methode „getInstance()“ liefert die einzige Instanz der Klasse zurück.
* Ist synchronisiert und somit thread-sicher.
*/
public synchronized static Singleton getInstance()
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
Nachteil dieser Variante ist, dass auch nach der Instanziierung jeder Lesezugriff über getInstance()
synchronisiert ist und so mehrere gleichzeitig zugreifende Threads sich gegenseitig blockieren.
Implementierungen, die mittels „double-checked locking“ bei bereits existierender Instanz auf die Synchronisation verzichten, sind im Allgemeinen nicht threadsicher.[11]
Lazy-Instantiierung
[Bearbeiten | Quelltext bearbeiten]In Java ist diese Implementierung dem Lazy-Creation-Ansatz vorzuziehen. Die Initialisierung findet durch das späte Initialisieren der Klasse erst statt, wenn die Klasse Singleton
referenziert wird.[12] Da der Zugriff nur via getInstance()
erfolgt, ist dies auch der spätest mögliche Zeitpunkt und entspricht somit der Lazy-Evaluation ohne den Synchronisierungs-Overhead.
public final class Singleton {
/** Privates Klassenattribut, einzige Instanz der Klasse wird erzeugt. */
private static final Singleton INSTANCE = new Singleton();
/** Konstruktor ist privat, darf nicht von außen aufgerufen werden. */
private Singleton() {}
/** Statische Methode „getInstance()“ liefert die einzige Instanz der Klasse zurück. */
public static Singleton getInstance() {
return INSTANCE;
}
// Hier folgen die Variablen des Singletons (nicht static!).
// Nun kommen die Public-Methoden, über die auf das Singleton zugegriffen wird,
// und schlussendlich noch die (privaten) Methoden, die die Implementierung enthalten.
// Wichtig: Methoden, die auf Instanz-Variablen zugreifen, müssen mit entsprechenden Mitteln
// synchronisiert werden, da es das Singleton nur einmal gibt und die Variablen somit automatisch global sind
// und von mehreren Threads gleichzeitig darauf zugegriffen werden kann.
}
public final class Singleton {
/** Private Klasse, einzige Instanz von Singleton wird beim Laden von Holder erzeugt. */
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}
/** Konstruktor ist privat, darf nicht von außen aufgerufen werden. */
private Singleton() {}
/** Statische Methode „getInstance()“ liefert die einzige Instanz der Klasse zurück. */
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
Hierdurch können andere statische Methoden von Singleton
gerufen oder in dieser definierte Konstanten referenziert werden, ohne INSTANCE
bereits zu erzeugen.
Implementierung in Perl
[Bearbeiten | Quelltext bearbeiten]Die Methode instance gibt $instance zurück, bzw. initialisiert es vorher noch, wenn dies noch nicht geschehen ist.
package My::Singleton;
use strict; use warnings;
my $instance;
sub instance() {
return $instance or $instance = bless {};
}
Dies kann dann mit dem folgenden Code genutzt werden:
use My::Singleton;
my $eins = My::Singleton->instance; # eine neue Instanz
my $zwei = My::Singleton->instance; # die gleiche Instanz
Threadsicher
[Bearbeiten | Quelltext bearbeiten]Hier wird $instance
bereits bei der Initialisierung von Singleton angelegt. Durch das :shared
wird das Beispiel außerdem thread-safe.
package Singleton;
use strict; use warnings;
my $instance :shared = bless {};
sub instance() { return $instance; }
42;
Mit CPAN-Modul
[Bearbeiten | Quelltext bearbeiten]Etwas erweiterte Funktionalität bietet das CPAN-Modul Class::Singleton.
Implementierung in PHP
[Bearbeiten | Quelltext bearbeiten]Ab PHP Version 5
[Bearbeiten | Quelltext bearbeiten]<?php
final class Singleton {
// Anlegen der Instanz
private static $instance = NULL;
// Konstruktor privat, damit die Klasse nur aus sich selbst heraus instanziiert werden kann.
private function __construct() {}
// Diese statische Methode gibt die Instanz zurueck.
public static function getInstance() {
if (NULL === self::$instance) {
self::$instance = new self;
}
return self::$instance;
}
// Klonen durch private Klonmethode von außen verbieten.
private function __clone() {}
}
// Erzeugen einer Instanz der Klasse
$singleton = Singleton::getInstance();
?>
Implementierung in Python
[Bearbeiten | Quelltext bearbeiten]Ab Python Version 2.2
[Bearbeiten | Quelltext bearbeiten] class Singleton(object):
def __new__(type, *args):
# Falls es noch keine Instanz dieser Klasse gibt, wird eine erstellt und in _the_instance abgelegt.
# Diese wird dann jedes Mal zurückgegeben.
if not '_the_instance' in type.__dict__:
type._the_instance = object.__new__(type)
return type._the_instance
def __init__(self):
if not '_ready' in dir(self):
# Der Konstruktor wird bei jeder Instanziierung aufgerufen.
# Einmalige Dinge wie zum Beispiel die Initialisierung von Klassenvariablen müssen also in diesen Block.
self._ready = True
Borg-Pattern
[Bearbeiten | Quelltext bearbeiten]Unter Python gibt es auch mehrere Ansätze für das Singleton-Entwurfsmuster. Eine Umsetzung des Monostate-Prinzips ist auch als Borg-Pattern bekannt:
class Borg(object):
_shared = {}
def __new__(cls,*args,**kwargs):
inst = object.__new__(cls)
inst.__dict__ = cls._shared
return inst
Implementierung in Visual Basic .NET
[Bearbeiten | Quelltext bearbeiten]Die folgende Implementierung ist threadsicher.
Public Class Singleton
' Variable zur Speicherung der einzigen Instanz
Private Shared instance As Singleton = Nothing
' Hilfsvariable für eine sichere Threadsynchronisierung.
Private Shared ReadOnly mylock As New Object()
' Konstruktor ist privat, damit die Klasse nur aus sich selbst heraus instanziiert werden kann.
Private Sub New()
'
End Sub
' Diese Shared-Methode liefert die einzige Instanz der Klasse zurück.
Public Shared Function GetInstance() As Singleton
SyncLock (mylock)
If instance Is Nothing Then
instance = New Singleton
End If
End SyncLock
Return instance
End Function
End Class
' Zugriff über Dim s As Singleton = Singleton.GetInstance()
Einzelnachweise
[Bearbeiten | Quelltext bearbeiten]- ↑ Paul DiLascia: Singleton Class Private Constructor, C# Singleton Class, and More. In: MSDN Magazin. Microsoft, abgerufen am 13. April 2013 (englisch).
- ↑ MethodImplOptions Enumeration. In: MSDN. Microsoft, abgerufen am 13. April 2013 (englisch).
- ↑ Judith Bishop: C# 3.0 Design Patterns. O’Reilly, 2008, ISBN 978-0-596-52773-0 (englisch).
- ↑ Jon Skeet: Implementing the Singleton Pattern in C#. Abgerufen am 13. April 2013 (englisch).
- ↑ Joshua Bloch: Creating and destroying Java object. InformIT, 16. April 2008, abgerufen am 13. April 2013 (englisch).
- ↑ Boris Brock: A Reusable Base Class for the Singleton Pattern in C#. In: Code Project. 5. April 2013, abgerufen am 13. April 2013 (englisch).
- ↑ Martin Lapierre: Generic Singleton Pattern using Reflection, in C#. In: Code Project. 9. Juni 2009, abgerufen am 13. April 2013 (englisch).
- ↑ Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides: Entwurfsmuster. 5. Auflage. Addison-Wesley, Bonn 1996, ISBN 3-8273-1862-9, S. 158 ff.
- ↑ Scott Meyers: Mehr effektiv C++ programmieren. 1. Auflage. Addison-Wesley-Longman, 1998, ISBN 3-8273-1275-2, S. 146 ff.
- ↑ Joshua Bloch: Effective Java. 2. Auflage. Addison-Wesley Professional, 2008, ISBN 978-0-13-277804-6 (englisch, books.google.at [abgerufen am 26. Januar 2014]).
- ↑ Peter Haggar: Double-checked locking and the Singleton pattern. In: Java Library. IBM, abgerufen am 13. April 2013 (englisch).
- ↑ Tim Lindholm, Frank Yellin: The JavaTM TMVirtual Machine Specification. 2. Auflage. S. Abschnitt 2.17.4 (docs.oracle.com [abgerufen am 22. Januar 2007]). docs.oracle.com ( des vom 14. April 2012 im Internet Archive) Info: Der Archivlink wurde automatisch eingesetzt und noch nicht geprüft. Bitte prüfe Original- und Archivlink gemäß Anleitung und entferne dann diesen Hinweis.