제이온

[Effective Java] Item 3: Singleton-Eigenschaft mit privatem Konstruktor oder Enum-Typ garantieren

  • Verfasst in: Koreanisch
  • Land: Alle Ländercountry-flag
  • IT

Erstellt: 2024-04-27

Erstellt: 2024-04-27 00:48

Singleton

Das Konzept von Singleton

Singleton bezeichnet eine Klasse, die nur eine einzige Instanz erstellen kann. Typische Beispiele für Singletons sind zustandslose Objekte oder eindeutige Systemkomponenten. Singleton-Klassen sind jedoch schwer zu testen, es sei denn, der Typ wird über eine Schnittstelle definiert und dessen Implementierung separat definiert.


So erstellen Sie ein Singleton

Methode mit public static final-Feld



Der private Konstruktor wird nur einmal beim Initialisieren der Elvis-Instanz aufgerufen und garantiert, dass es sich um die einzige Instanz im gesamten System handelt. Es ist jedoch möglich, den privaten Konstruktor mit AccessibleObject.setAccessible() aufzurufen. Diese Manipulation über Reflection kann verhindert werden, indem beim Erstellen eines zweiten Objekts eine Ausnahme ausgelöst wird.


  • Vorteile
    • Die Singleton-Eigenschaft der Klasse ist in der API klar ersichtlich.
    • Einfach.


Methode mit statischer Fabrikmethode, die als public static bereitgestellt wird


Abgesehen von der Manipulation über Reflection garantiert auch diese Methode, dass es sich um die einzige Instanz im gesamten System handelt. Das Feld wurde lediglich in private geändert und die Objektrückgabe erfolgt über eine statische Fabrikmethode.


  • Vorteile
    • Die API kann geändert werden, ohne dass das Singleton aufgehoben werden muss.
      • Beispielsweise kann die statische Fabrikmethode für jeden Thread eine andere Instanz zurückgeben.
    • Sie kann bei Bedarf in eine generische Singleton-Fabrikmethode geändert werden.
    • Der Methodenverweis der statischen Fabrik kann als Anbieter verwendet werden.
      • Beispielsweise kann anstelle von Elvis::getInstance Supplier<Elvis> verwendet werden.


Wenn Sie die oben genannten Vorteile nicht nutzen müssen, ist es besser, die erste Methode zu verwenden.


Verwendung eines Aufzählungsdatentyps


Die beste Methode ist die Verwendung eines Aufzählungsdatentyps. Im Vergleich zu den beiden oben genannten Methoden ist sie sowohl gegen Reflection-Angriffe geschützt als auch sauberer im Code. Außerdem, wie weiter unten beschrieben, haben die beiden oben genannten Methoden den Nachteil, dass beim Serialisieren zusätzlicher Code hinzugefügt werden muss.

Es ist jedoch zu beachten, dass ein zu erstellendes Singleton zwar eine Schnittstelle erben kann, aber keine Klasse erben kann.


Punkte, die bei der Serialisierung einer Singleton-Klasse zu beachten sind

Wenn Sie eine Singleton-Klasse serialisieren möchten, die mit der ersten oder zweiten Methode erstellt wurde, müssen Sie neben der einfachen Implementierung von Serializable alle Instanzfelder als transient deklarieren und die Methode readResolve() überschreiben und bereitstellen.



Quelle

Kommentare0