it-swarm-eu.dev

Was ist der Unterschied zwischen rein statischen Methoden und dem Anwenden eines Singleton-Musters?

Ich erstelle eine Datenbank zum Speichern von Informationen über die Benutzer meiner Website (ich verwende stuts2 und damit Java EE-Technologie). Für die Datenbank werde ich einen DBManager erstellen. Sollte ich Singleton anwenden Muster hier oder eher alle Methoden statisch machen?

Ich werde diesen DBManager für grundlegende Dinge wie das Hinzufügen, Löschen und Aktualisieren von Benutzerprofilen verwenden. Daneben werde ich für alle anderen Abfragezwecke verwenden, um beispielsweise herauszufinden, ob bereits ein Benutzername vorhanden ist, und um alle Benutzer für Verwaltungszwecke und ähnliches zu gewinnen.

Meine Fragen

  • Was ist der Vorteil eines Singleton-Musters?
  • Welches Ding passt hier am besten? Alle statischen Methoden oder ein Singleton-Muster?
  • Bitte vergleichen Sie beide.

P.S. Die Datenbank ist größer als diese. Hier spreche ich nur über die Tabellen, die ich zum Speichern von Benutzerinformationen verwenden werde.

28
shahensha

Warum sind Singleton und statische Methoden Ihre einzigen Optionen?

Aus meiner Sicht sind beide Optionen ziemlich schlecht. Lesen Sie das Singleton AntiPattern . Die meisten Anwendungsfälle des Singleton-Musters sind falsch.

In Ihrem Fall würde ich ein Instanzobjekt verwenden und die Abhängigkeitsinjektion (wenn Sie ein DI-Framework verwenden) oder ein Service Locator/Registry-Muster verwenden

20
Tazzy531

Mit einer Singleton-Klasse haben Sie mehr Kontrolle darüber, wie Sie das erstellte Objekt verwalten.

Erstens ist ein Singleton ein Objekt. Die statische Methode gibt eine Instanz des Objekts zurück und ermöglicht es Ihnen, nur eine oder mehrere Instanzen zu erstellen, wenn Sie dies wünschen.

Singletons sind auch faul geladen, was bedeutet, dass sie erst beim ersten Aufruf instanziiert werden.

Ein Singleton verwendet keine statischen Methoden, sodass Sie keine Probleme haben, ihn in einem nicht statischen Kontext zu verwenden.

Singletons können erweitert/unterklassifiziert werden.

Da es sich um Objekte handelt, können sie in andere Objekte injiziert werden, wodurch einige großartige Entwurfsmuster unter Verwendung der Konzepte der Abhängigkeitsinjektion erstellt werden können. So funktioniert beispielsweise das Spring Bean IoC-Modell (Inversion of Control Dependency Injection).

15
jmort253

Weder ist ideal, aber vor allem nicht ein Haufen Statik. Hier ist ein Beispiel aus meiner Praxis. Wir haben mit einer Datenbank gesprochen. Alle sagten "es wird nur einen geben", also benutzte jemand einen von Spring konfigurierten Standard-Singleton. Dann wurde eine neue Anforderung hinzugefügt: um unsere Daten in eine andere (entfernte) Datenbank kopieren zu können. Hoppla. Da wir ein tatsächliches Objekt hatten, das die Datenbank darstellt, und dies eine "selten verwendete" Funktion war, konnte ich es hacken, indem ich eine temporäre Kopie erstellte und Felder und Werte änderte. Wäre dies jedoch mit globaler Statik implementiert worden, wäre es eine gewesen echte Katastrophe.

Nach meiner Erfahrung, wenn "sie" sagen, dass es nur eine Datenbank, einen Benutzer, eine Anwendung, ein Hauptfenster usw. geben wird, "sie" sind falsch. Mit einem Singlton haben Sie zumindest eine Chance, es zu überarbeiten und zu reparieren.

3
user949300

Was ist der Unterschied zwischen rein statischen Methoden und dem Anwenden eines Singleton-Musters?

Beide haben den gleichen Effekt: Sie können eine Klassenmethode aufrufen, ohne sich darum zu kümmern, wie eine Instanz der Klasse abgerufen wird, die die Methode enthält.

Wenn Sie jedoch statische Unittesting-Methoden implementieren möchten, sind diese problematischer, da sie nicht einfach verspottet sein können.

Aus der Testperspektive ist es einfacher, Code neu zu schreiben, der Singeltons verwendet, um sie mit Mocks nicht zu testen.

Die flexibelste Lösung wäre, Dependency_injection zu haben, egal ob Sie ein Di-Container-Framework verwenden (wie von @ Tazzy531 vorgeschlagen) oder Abhängigkeiten per Code verdrahten.

3
k3b

Ich hoffe, dass dies hier nur die Hauptfrage beantwortet.

Es gibt bereits wenige gute Antworten in SO . Ich werde sie nur zitieren.

Beste Antwort von Heinzi :

Ein Singleton wird verwendet, um einer Anwendung eine Art globalen Status hinzuzufügen. Wenn es zustandslos ist, sehe ich auch keinen Sinn darin, einen Singleton zu verwenden, es sei denn

  • sie erwarten, es in absehbarer Zeit mit Staat zu erweitern oder
  • sie benötigen eine Objektinstanz aus einem bestimmten technischen Grund (zum Beispiel) für die Anweisung C # SyncLock, obwohl dies bereits ziemlich weit hergeholt ist) oder
  • sie benötigen eine Vererbung, d. h. Sie möchten Ihren Singleton problemlos durch einen anderen ersetzen können, indem Sie dieselbe Schnittstelle, aber eine andere Implementierung verwenden. Beispielsweise gibt die Methode Toolkit.getDefaultToolkit() in Java] einen Singleton zurück, dessen genauer Typ systemabhängig ist.

Hoher relevanter Kommentar von back2dos :

(...) Singletons werden missbraucht, um globale Staaten einzuführen. Der Zweck eines Singletons besteht nicht darin, ein Objekt global verfügbar zu machen, sondern zu erzwingen, dass ein Objekt nur einmal instanziiert wird. Globale Objekte sind ein notwendiges Übel. Sofern dies nicht wirklich erforderlich ist, sollte versucht werden, sie nicht zu verwenden, da sie im Allgemeinen zu einer hohen Kopplung mit SomeSingleton.getInstance (). SomeMethod () führen.

tzaman hat auch eine gute Antwort geschrieben:

Ich konnte einen Fall sehen, in dem ein zustandsloser Singleton anstelle einer statischen Methodenklasse verwendet wurde, nämlich für Dependency Injection .

Wenn Sie über eine Hilfsklasse von Dienstprogrammfunktionen verfügen, die Sie direkt verwenden, wird eine versteckte Abhängigkeit erstellt. Sie haben keine Kontrolle darüber, wer es wo verwenden kann. Wenn Sie dieselbe Hilfsklasse über eine zustandslose Singleton-Instanz einfügen, können Sie steuern, wo und wie sie verwendet wird, und sie bei Bedarf ersetzen/verspotten/usw.

Wenn Sie es zu einer Singleton-Instanz machen, stellen Sie einfach sicher, dass Sie nicht mehr Objekte des Typs als erforderlich zuweisen (da Sie immer nur eines benötigen).

Und schließlich Sebastien antwortete sich auch ganz gut:

Eigentlich habe ich eine andere Antwort gefunden, die hier nicht erwähnt wird: Statische Methoden sind schwerer zu testen.

Es scheint, dass die meisten Test-Frameworks hervorragend zum Verspotten von Instanzmethoden geeignet sind, aber viele von ihnen behandeln das Verspotten statischer Methoden nicht in angemessener Weise.

Davon abgesehen empfehle ich die Verwendung des Toolbox-Musters .

2
cregox