Wann und wie sollen wir einen Konstruktor verwenden
Foo bar = new Foo();
Und wann und wie sollen wir getInstance () verwenden (statische Factory-Methoden)
Foo bar = Foo.getInstance();
Was ist der Unterschied zwischen diesen beiden? Ich habe immer einen Konstruktor verwendet, aber wann sollte ich getInstance()
stattdessen verwenden?
getInstance()
oder schreiben Sie eine Methode namensgetInstance()
?Foo.newInstance()
.Foo.getInstance()
ist eine Konvention zum Abrufen der Singleton-Instanz einer Klasse. Sie sollten Ihr Beispiel korrigieren undFoo.newInstance()
stattdessen verwenden.Antworten:
Jeder scheint sich auf Singletons zu konzentrieren, während ich denke, dass es sich bei der Frage tatsächlich um Konstruktor- und statische Factory-Methoden handelt .
Dies ist eigentlich Punkt 1: Betrachten Sie statische Factory-Methoden anstelle von Konstruktoren von Effective Java von Joshua Bloch:
Vorteile (zitiert das Buch):
Nachteile (zitiert immer noch das Buch):
quelle
protected
Unterklassen zulassen, aber hat Client-Code einen echten Vorteil, wenn ein neues Objekt erstellt und sein Konstruktor aufgerufen wird, anstatt eine statische Factory-Methode aufzurufen? Es scheint mir, dass ein verketteter Konstruktoraufruf semantisch eine Instanzmethode ist, während die Sequenz "Unitialisiertes Objekt erstellen und seinen Konstruktor aufrufen" semantisch einem statischen Factory-Methodenaufruf entspricht.Sie haben zwei Fragen: Wann soll ich eine Methode aufrufen
getInstance()
und wann soll ich eine erstellen ?Wenn Sie sich entscheiden, ob Sie eine
getInstance()
Methode aufrufen möchten, ist dies ganz einfach. Sie müssen nur die Klassendokumentation lesen, um herauszufinden, wann Sie sie aufrufen sollten. Zum BeispielNumberFormat
bietet einen Konstruktor und eingetInstance()
Verfahren; DiegetInstance()
Methode gibt Ihnen eine lokalisierteNumberFormat
. FürCalendar
, auf der anderen Seite wird der Konstruktor geschützt. Du musst anrufengetInstance()
, um einen zu bekommen.Wenn Sie entscheiden, ob Sie eine
getInstance()
Methode erstellen möchten, müssen Sie entscheiden, was Sie erreichen möchten. Entweder möchten Sie nicht, dass Benutzer Ihren Konstruktor aufrufen (Sie erstellen einen Singleton oder eine Factory ), oder es macht Ihnen nichts aus (wieNumberFormat
oben, wo sie einige Objekte für den Aufrufer initialisieren).Um es kurz zu machen? Machen Sie sich keine Sorgen, wenn Sie
getInstance()
Methoden in Ihrem eigenen Code erstellen. Wenn sich die Zeit ergibt, in der sie nützlich sein werden, wissen Sie Bescheid. Und wenn Sie im Allgemeinen den Konstruktor einer Klasse aufrufen können , sollten Sie dies wahrscheinlich tun, selbst wenn die Klasse einegetInstance()
Methode bereitstellt .quelle
Die Verwendung für getInstance-Methoden:
Meistens ist Ihr Objekt jedoch ein einfaches POJO, und die Verwendung öffentlicher Konstruktoren ist die praktischste und naheliegendste Lösung.
U1: getInstance aus einer anderen Klasse
So geben Sie eine Instanz einer anderen Klasse zurück:
NumberFormat.getInstance
Methoden tun dies, da sie tatsächlich Instanzen von zurückgebenDecimalFormat
.U2: Singleton-Probleme
Das Singleton-Muster schränkt viele der Vorteile der objektorientierten Programmierung ein. Singletons haben im Allgemeinen private Konstruktoren, daher können Sie sie nicht erweitern. Da Sie über die Methode getInstance darauf zugreifen und keine Schnittstelle referenzieren, können Sie es nicht gegen eine andere Implementierung austauschen.
quelle
Wenn Sie beide verwenden können, klingt dies wie ein schlecht implementiertes Singleton-Muster .
Verwenden Sie die zweite Option, wenn Sie nur eine einzige Instanz der Klasse in Ihrem System haben möchten, und machen Sie den Konstruktor dann privat.
Verwenden Sie die erste Option, um mehrere Objekte der Klasse zu erstellen.
ABER geben Sie Ihrer Klasse nicht beide Möglichkeiten.
Achten Sie darauf, Singletons nicht zu stark zu verwenden. Verwenden Sie sie nur, wenn wirklich nur eine Instanz im System vorhanden sein soll. Andernfalls würden Sie die Möglichkeiten der Wiederverwendung Ihrer Klasse in anderen Projekten einschränken. Es klingt interessant, getInstance von überall in Ihrem Projekt aufrufen zu können, aber das macht unklar, wem diese Instanz tatsächlich gehört: niemand und / oder alle. Wenn Sie viele Singletons in einem Projekt haben, können Sie darauf wetten, dass das System (normalerweise) schlecht ausgelegt ist. Singletons sollten mit Vorsicht verwendet werden. Es gelten die gleichen Hinweise wie für globale Variablen.
quelle
Ein Fall, in dem ich immer eine statische Fabrik einem normalen Konstruktor vorziehe, ist, wenn ich weiß, dass die Objektkonstruktion langsam sein wird. Ich mache eine einfache Initialisierung auf dem Konstruktor, aber wenn ich etwas Schweres erstellen muss, verwende ich eine statische Methode und dokumentiere das Verhalten.
quelle
Singletons sind böse. Die Probleme, die ich im Zusammenhang damit gesehen habe, betreffen nicht die Wiederverwendung oder Erweiterbarkeit eines Systems (obwohl ich sehen konnte, wie dies auftreten könnte), sondern vielmehr, dass ich nicht zählen kann, wie oft ich obskure Fehler in einem System gesehen habe System, das aus Singletons entsteht.
Wenn Sie einen Singleton verwenden müssen, stellen Sie sicher, dass sein Umfang extrem eng ist, dh begrenzen Sie die Anzahl der anderen Objekte in Ihrem System, die davon wissen, mit Bedacht.
quelle