Der Artikel beschreibt, wie Sie eine Klasse, die nach dem Singleton-Muster. Die Klasse beschrieben, kümmert sich um den singleton Anforderungen und Auswirkungen sich tatsächlich aus dem Programmierer zur Verwendung der Klasse als alle anderen.

Ein Singleton ist eine Klasse, unterstützt die Schaffung von nur ein Objekt. Es ist wie Sie Ihren Computer - es gibt nur ein Keyboard. Also, wenn Sie wurden schriftlich Delphi-Code, der Ihrem Computer simuliert, würden Sie wollen nur ein Objekt Instanz, um mit der Tastatur lesen, schreiben, und Kontrolltätigkeiten.

Artikel über Singleton Klassen sind selten, aber es gibt einige im Internet. Ich habe einige in Zeitschriften zu. Aber keines dieser Artikel enthalten Beispielcode zur Schaffung eines echten Singleton Klasse.

Mit "echten" Ich meine, dass die Klasse selbst die Anwendung der ein-Instanz Anforderung, anstelle von aus, dass die Aufgabe der Programmierer. All die Artikel, die ich gesehen habe, so weit haben, die Programmierer, die Klasse in besonderer Weise für die Durchsetzung der singleton Muster.

In diesem Artikel werden Sie sehen, wie die Schaffung eines echten Singleton Klasse, die Logik für die Durchsetzung der Ein-fall-Regel.

Hinweis:Der konventionelle Ansatz, in dem die ein-Beispiel-Regel beibehalten wird explizit durch den Programmierer, ist nicht ohne Verdienst. Real singleton Klassen, wie die, die ich hier wirksam verstecken die Details und das Wissen um die singleton Muster aus der Programmierer. Der Programmierer ist erleichtert, der die Aufgabe, die Durchsetzung der Muster - das ist gut - aber die Programmierer können auch nicht die besondere Art der Klasse, das ist schlecht. Wenn Sie nicht wissen, dass die Klasse ist eine Singleton Klasse, dann werden alle Arten von Fehlern auftreten. Sie wurden gewarnt!


Schreiben Sie den Code


Unser Ziel ist es, eine Klasse, die verwendet werden können wie folgt aus:


Verfahren Test;
var
S1, S2: TSingleton;
beginnen
s1: = TSingleton.Create;
s2: = TSingleton.Create;
/ / Etwas mit S1 und S2 hier
s2.Free;
s1.Free;
end;



(Ich habe den Versuch ... schließlich Blöcke und andere Schutzbestimmungen für Einfachheit halber.)

Das Ziel ist es, die TSingleton Klasse so verhalten, dass die beiden S1 und S2, beziehen sich die auf dasselbe Objekt. Hier ist, was wir zu tun haben:

  • Instanziieren das Objekt zum ersten Mal erstellen ist (wenn s1 wird oben)
  • Stellen Sie sicher, dass, wenn ein anderer Erstellen ausgeführt wird (S2), dem bestehenden Objekt wiederverwendet werden, anstatt ein weiteres erstellt
  • Vermeiden Sie das Objekt zu zerstören, wenn es nicht der letzte Hinweis, dass zerstört wird (wenn s2 ist frei)
  • Zerstören Sie die Instanz, wenn der letzte Verweis ist zerstört (wenn s1 ist frei oben)


Gibt es eine Möglichkeit, um die Schaffung und Vernichtung von einem neuen Objekt in Delphi? Es ist sicher. In der Klasse TObject (die Mutter aller Objekte, die pun ()), gibt es zwei Methoden, die wir nutzen können:


Klasse Funktion newInstance: TObject; virtuelle;
Verfahren FreeInstance; virtuelle;



NewInstance ist verantwortlich für die Zuteilung von Speicher, um eine neue Instanz der Klasse, und FreeInstance ist verantwortlich für die Freigabe, dass Speicher, wenn die Klasse mit ihm durch.

Diese Methoden kontrollieren, was passiert, wenn das Objekt erstellt wird und wenn das Objekt zerstört wird. Wenn wir diesen Code zu überschreiben, wir können die Standard-Verhalten zu sagen, eine Arbeit, die die Singleton Klasse erfordert. Nichts ist.

Tracking Fällen ist ein wenig komplizierter. Wir müssen:

  1. Verfolgen Sie jede bestehende Instanz der Klasse
  2. Verfolgen Sie, wie viele Hinweise gibt es zu diesem Fall
  3. Erstellen Sie ein neues Objekt nur dann, wenn keine Instanz gibt
  4. Zerstören Sie das Objekt, wenn der letzte Verweis entfernt


Um die Spur einer vorhandenen Instanz, werden wir eine globale Variable. Eigentlich ist die Variable wird letztlich erklärt werden in der Umsetzung Teil einer Einheit, so dass es nicht um eine echte globale Variable. Doch der Umfang muss ausreichend sein, um alle erstellen und kostenlose Anrufe. Wir rufen die Variable Instanz, so dass wir wissen, was es bezieht sich auf.

Da für die Verfolgung, wie viele Hinweise gibt, benötigen wir noch eine weitere Variable. Wir können es in der Klasse oder ist es eine Art von globaler wie Instanz. Ich werde sich für die letztere, sondern tun, was Sie am besten ist. Ich werde Namen dieser Variablen Ref_Count.

Wir haben nun zwei Variablen:


var
Instanz: TSingleton = nil;
Ref_Count: Integer = 0;



Ich initialisieren die Variablen, so dass sie zunächst keine Müll. Ich weiß, dass der Compiler tut dies automatisch, so dass dies nur eine Frage der Lesbarkeit.

Wir müssen erklären, dass TSingleton Klasse über die Variable-Block, und wenn Sie einen Blick auf die Beispiel-Dateien, können Sie am Ende dieses Artikels finden Sie, dass ich haben die Erklärung in der Schnittstelle von das Gerät, so dass es sichtbar ist.

Hier ist die Erklärung des TSingleton Klasse:


Typ
TSingleton = Klasse
öffentlichen
Klasse Funktion newInstance: TObject; override;
Verfahren FreeInstance; override;
Klasse Funktion RefCount: Integer;
end;



Ich habe die RefCount-Funktion, so dass wir sehen können, dass es tatsächlich funktioniert, und es ist oft sehr handlich, um lesen zu können, wie viele Verweise auf das Objekt vorhanden ist. Es ist nicht erforderlich, so dass Sie nicht haben, um sie auf Ihre singleton Klassen, wenn Sie sie nicht benötigen.

Ok, jetzt für die Umsetzung der drei Methoden:


Verfahren TSingleton.FreeInstance;
beginnen
Dezember (Ref_Count);
if (Ref_Count = 0) dann
beginnen
Beispiel: = nil;
/ / Destroy privaten Variablen hier
FreeInstance geerbt;
end;
end;

Klasse Funktion TSingleton.NewInstance: TObject;
beginnen
if (nicht zugeordnet (Instanz)), dann
beginnen
Beispiel: = newInstance geerbt;
/ / Initialize privaten Variablen hier wie folgt aus:
/ / TSingleton (Ergebnis). Variable: = Value;
end;
Result: = Instanz
Inc (Ref_Count);
end;

Klasse Funktion TSingleton.RefCount: Integer;
beginnen
Result: = Ref_Count;
end;



Und das war's!
Beim Aufruf des Konstruktors TSingleton, ein Anruf wird auf die Methode, die in newInstance TObject. Diese Methode stellt Speicher zu halten, das neue Objekt und liefert es an den Konstruktor. Der Konstruktor verwendet, dass Speicher und schließlich gibt einen Pointer auf den Speicher, um den Code ein, den Konstruktor genannt. Dieser Zeiger wird in der Regel in einer Variable gespeichert, während das Objekt verwendet wird.

Ich habe die newInstance Methode überschrieben, so dass er die Aufteilung des Speichers nur dann, wenn keine Instanz der Klasse existiert. Wenn es eine vorhandene Instanz, die Funktion liefert einfach, dass beispielsweise an den Konstruktor übergeben, so dass es wieder verwendet werden.

Wenn wir den Konstruktor drei Mal, ein Objekt erstellt wird nur die erste Zeit. Die beiden anderen fordert einfach Wiederverwendung das erste Objekt. Der Verweis count Variable lassen Sie uns wissen, dass wir drei Verweise auf die einzige Instanz.

Wenn das Programm die destructor, einen Aufruf an FreeInstance ist in der Lage, den Speicher, die im Konstruktor. Diese Methode ist auch überschrieben werden, so dass das Objekt zerstört wird nur, wenn der letzte Verweis entfernt wird.

Wenn Sie beabsichtigen, ein individuelles Programm in einer multithreaded, behandeln das Objekt, wie man es jede Variable Sie zwischen Threads. Denn das ist genau das, was Sie tun: Anteil es zwischen den Fäden. So müssen Sie besonders vorsichtig, wenn Änderungen der Daten.


Einfachheit selbst


Wie Sie sehen können, so dass ein Singleton Klasse ist es nicht erforderlich, viel Mühe, genau das richtige Wissen und ein paar Zeilen Code. Mein Code funktioniert in Delphi 5. Die Technik wird wohl funktionieren, mit älteren Versionen von Delphi, aber ich habe es noch nicht getestet, damit ich keine Garantien.

Bevor ich Ihnen die Datei zu spielen, lassen Sie mich Ihnen ein paar Worte der Warnung.


  • Nicht Abstieg von einem Singleton Klasse. Der Grund dafür ist, dass es nur eine Instanz und Fundstelle count Variable. Wenn Sie ergeben sich zwei Klassen von TSingleton, nur ein Objekt erstellt werden soll. Die andere Klasse Wiederverwendung das Objekt, das ein Beispiel von einer anderen Klasse. Sie nicht diesen Weg!
  • Sie können nicht singleton Komponenten aus dem einfachen Grund des Eigentums. Eine Komponente ist im Besitz von einem Formular und einer Komponente können nicht im Besitz von mehreren anderen Komponenten.
  • Denken Sie daran, dass der Konstruktor und Destruktor aufgerufen, für jedes neue Referenz, wie sie erstellt und vernichtet werden. Nicht initialisieren private Variablen im Konstruktor und nicht frei in der Destruktor. Stattdessen bauen, dass Code in das newInstance und die FreeInstance Methoden, wie in den Kommentaren.
  • Die Reihenfolge der Anpassung Ref_Count in den beiden Methoden in Verbindung mit dem Rest der Code in diesen beiden Methoden ist von entscheidender Bedeutung. Es hat zu tun mit der richtigen Schöpfung und Zerstörung, wenn etwas schief läuft. Wenn Ihr Code Initialisierung wirft eine Ausnahme, die Ordnung der Dinge, wie oben gezeigt werden dafür sorgen, dass die Klasse zerstört werden. Alter diesen Code auf eigene Gefahr!

    Die Datei, die Sie herunterladen können ist nur eine Kopie der Einheit, die erklärt, die Singleton Klasse in diesem Artikel beschrieben.

    Link zur Datei: 15083 CodeCentral Eintrag.

    Ich bin sicher, Sie finden ein paar Orte, an denen ein individuelles Klasse kommt in handliches und jetzt haben Sie die Werkzeuge zum Erstellen Ihrer eigenen! Wenn Sie möchten, nehmen Sie Kontakt mit mir, meine E-Mail ist lasse@cintra.no

    Frohes Programmieren!