Liste von Singleton-Implementierungen

aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen Zur Suche springen

Dies ist eine Liste von Implementierungen des Entwurfsmusters Singleton in unterschiedlichen Programmiersprachen.

(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();
*/

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);

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:

  1. 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.
  2. 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 Methode lock(this){ … } hat sich als unzureichend herausgestellt, weil fehlerhafter oder böswilliger Code durch den Aufruf Monitor.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);

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.

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

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;

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

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

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]
  1. Paul DiLascia: Singleton Class Private Constructor, C# Singleton Class, and More. In: MSDN Magazin. Microsoft, abgerufen am 13. April 2013 (englisch).
  2. MethodImplOptions Enumeration. In: MSDN. Microsoft, abgerufen am 13. April 2013 (englisch).
  3. Judith Bishop: C# 3.0 Design Patterns. O’Reilly, 2008, ISBN 978-0-596-52773-0 (englisch).
  4. Jon Skeet: Implementing the Singleton Pattern in C#. Abgerufen am 13. April 2013 (englisch).
  5. Joshua Bloch: Creating and destroying Java object. InformIT, 16. April 2008, abgerufen am 13. April 2013 (englisch).
  6. Boris Brock: A Reusable Base Class for the Singleton Pattern in C#. In: Code Project. 5. April 2013, abgerufen am 13. April 2013 (englisch).
  7. Martin Lapierre: Generic Singleton Pattern using Reflection, in C#. In: Code Project. 9. Juni 2009, abgerufen am 13. April 2013 (englisch).
  8. Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides: Entwurfsmuster. 5. Auflage. Addison-Wesley, Bonn 1996, ISBN 3-8273-1862-9, S. 158 ff.
  9. Scott Meyers: Mehr effektiv C++ programmieren. 1. Auflage. Addison-Wesley-Longman, 1998, ISBN 3-8273-1275-2, S. 146 ff.
  10. 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]).
  11. Peter Haggar: Double-checked locking and the Singleton pattern. In: Java Library. IBM, abgerufen am 13. April 2013 (englisch).
  12. 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 (Memento des Originals 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.@1@2Vorlage:Webachiv/IABot/docs.oracle.com