Wie mache ich eine abstrakte Klasse, die jede abgeleitete Klasse zu Singleton zwingen soll? Ich benutze C #.
das würde nicht funktionieren, weil das Singleton irgendwo einen statischen Zugriff benötigt und das nicht erzwungen werden kann.
für singletonimplementation + Beispiele siehe: Implementieren des Singleton-Musters in C #
Singleton bedeutet, private Konstruktoren zu haben. Aber Sie wissen, dass private Mitglieder nicht vererbt werden können. In C ++ gab es Vorlagen, so dass Sie ein Singleton aus einer Vorlagenklasse erstellen konnten. In C # gibt es keine Vorlagen, daher müssen Sie für jedes gewünschte Singleton eigene private Konstruktoren schreiben.
Klassen in Java oder C # sind nicht "erstklassig". Der statische Teil einer Klasse kann nicht von Unterklassen geerbt oder überschrieben werden. Weitere Informationen finden Sie diese Antwort . Plus, Sie haben kein Konzept der Meta-Klasse.
In Sprachen wie Smalltalk oder Ruby können Sie eine neue Metaklasse Singleton
definieren, die eine Methode getInstance
definiert. Dann können Sie ClassA
und ClassB
als Instanzen der% metaclass Singleton
definieren. Dann stellen beide Klassen automatisch eine Methode getInstance
zur Verfügung, mit der die Instanzen objectA
oder objectB
erstellt werden können. Ist das nicht cool? Nun, in der Praxis benutzt man die Metaklasse nicht häufig, und das Singleton ist eigentlich die einzige Verwendung von ihnen, die Sinn macht und mir bewusst ist.
Hier ist ein (hässlicher) Weg, dies zu tun. Es könnte wahrscheinlich vereinfacht und verbessert werden, aber es ist mein erster Versuch.
Der Grundgedanke ist, zuerst die Basisklasse zu einer generischen abstrakten Klasse zu machen (wie in den obigen Kommentaren erwähnt), aber der type-Parameter ist von der Basisklasse selbst abhängig. Dadurch kann die Basisklasse die Singleton-Instanz des abgeleiteten Typs verarbeiten. Beachten Sie, dass alle abgeleiteten Klassen wie bei jeder Singleton-Klasse versiegelt sein sollten.
Als Nächstes ist ein geschützter Konstruktor erlaubt, muss aber eine Instanz einer speziellen Klasse, SingletonKey, akzeptieren, bei der es sich um einen modifizierten Singleton handelt. Abgeleitete Klassen haben Zugriff auf die SingletonKey-Klassendefinition, aber die Basisklasse behält die private Kontrolle über die einzige zulässige Instanz und somit über die Konstruktion aller abgeleiteten Objekte.
Drittens muss die Basisklasse in der Lage sein, den Konstruktor der abgeleiteten Klasse aufzurufen, aber das ist etwas schwierig. Der Compiler wird sich beschweren, wenn Sie versuchen, den abgeleiteten Schlüsselkonstruktor aufzurufen, da es nicht garantiert ist, dass er existiert. Die Lösung besteht darin, einen statischen Delegaten hinzuzufügen, den die abgeleitete Klasse initialisieren muss. Daher müssen alle abgeleiteten Klassen eine einfache Initialisierungsmethode bereitstellen. Diese Initialisierungsmethode sollte explizit aufgerufen werden, bevor Sie versuchen, im Code zum ersten Mal auf die Instanz zuzugreifen. Andernfalls tritt ein Laufzeitfehler auf.
%Vor%Ich glaube, ich habe versucht, etwas Ähnliches zu erreichen, d. h. eine gemeinsame Schnittstelle und das Singleton-Muster für eine Gruppe von Klassen durchzusetzen. Das war meine Lösung:
%Vor%Hier ist ein einfacher Test:
%Vor%Bitte beachten Sie, dass Sie die allgemeine Schnittstelle einfach aus der generischen abstrakten Singleton-Klasse entfernen können, wenn Sie nur die grundlegende "Vorlage" benötigen.