Gibt es einen Nachteil beim Schreiben eines langen Konstruktors?

8

Beeinflusst es die Zeit beim Laden der Anwendung? oder irgendwelche anderen Probleme dabei?

    
Aragorn 03.06.2010, 05:56
quelle

7 Antworten

24

Die Frage ist vage, was "lang" bedeutet. Hier sind einige mögliche Interpretationen:

Interpretation # 1: Der Konstruktor hat viele Parameter

Konstruktoren mit vielen Parametern können zu schlechter Lesbarkeit führen und es gibt bessere Alternativen.

Hier ist ein Zitat von Effektive Java 2. Ausgabe, Punkt 2: Betrachten Sie ein Builder-Muster, wenn Sie mit vielen Konstruktorparametern konfrontiert werden :

  

Traditionell haben Programmierer das telescoping constructor -Muster verwendet, in dem Sie einem Konstruktor nur die erforderlichen Parameter, ein anderes mit einem optionalen Parameter, ein drittes mit zwei optionalen Parametern und so weiter zur Verfügung stellen. ..

Das Teleskop-Konstruktormuster ist im Wesentlichen so:

%Vor%

Und jetzt können Sie Folgendes tun:

%Vor%

Sie können jedoch derzeit nicht nur name und isAdjustable festlegen und levels als Standard belassen. Sie können mehr Konstruktorüberladungen bereitstellen, aber die Zahl würde natürlich explodieren, wenn die Anzahl der Parameter wächst, und Sie könnten sogar mehrere boolean und int Argumente haben, was wirklich Unordnung schaffen würde.

Wie Sie sehen, ist dies kein angenehmes Schreibmuster und noch weniger angenehm zu benutzen (Was bedeutet "wahr" hier? Was ist 13?).

Bloch empfiehlt, ein Builder-Muster zu verwenden, mit dem Sie stattdessen Folgendes schreiben können:

%Vor%

Beachten Sie, dass jetzt die Parameter benannt sind, und Sie können sie in jeder beliebigen Reihenfolge festlegen, und Sie können diejenigen überspringen, die Sie bei den Standardwerten beibehalten möchten. Dies ist sicherlich viel besser als Teleskop Konstruktoren, vor allem, wenn eine große Anzahl von Parametern zu vielen der gleichen Typen gehören.

Siehe auch

Verwandte Fragen

Interpretation # 2: Der Konstruktor macht viel Arbeit, die Zeit kostet

Wenn die Arbeit zur Konstruktionszeit ausgeführt werden muss, macht es nicht wirklich einen Unterschied, ob sie im Konstruktor oder in einer Hilfsmethode ausgeführt wird. Wenn ein Konstruktor deligiert, aber an eine Hilfsmethode arbeitet, stellen Sie sicher, dass er nicht überschrieben werden kann, da dies zu vielen Problemen führen kann.

Hier ist ein Zitat von Effective Java 2nd Edition, Punkt 17: Design und Dokument für die Vererbung, oder verbieten Sie es :

  

Es gibt einige weitere Einschränkungen, die eine Klasse erfüllen muss, um Vererbung zuzulassen. Konstruktoren dürfen keine überschreibbaren Methoden direkt oder indirekt aufrufen. Wenn Sie diese Regel verletzen, führt dies zu einem Programmfehler. Der Superklassenkonstruktor wird vor dem Unterklassenkonstruktor ausgeführt, sodass die überschreibende Methode in der Unterklasse aufgerufen wird, bevor der Unterklassenkonstruktor ausgeführt wurde. Wenn die überschreibende Methode von einer vom Unterklassenkonstruktor durchgeführten Initialisierung abhängt, verhält sich die Methode nicht wie erwartet.

Hier ein Beispiel zur Veranschaulichung:

%Vor%

Wenn Base constructor overrideMe aufruft, hat Child die Initialisierung von final int x noch nicht beendet, und die Methode erhält den falschen Wert. Dies wird fast sicher zu Fehlern führen.

Interpretation # 3: Der Konstruktor macht eine Menge Arbeit, die zurückgestellt werden kann

Die Konstruktion eines Objekts kann schneller gemacht werden, wenn einige Arbeiten auf den Zeitpunkt verschoben werden, an dem sie tatsächlich benötigt werden; Dies wird als faule Initialisierung bezeichnet. Wenn zum Beispiel ein String erstellt wird, berechnet es seinen Hash-Code nicht tatsächlich. Es tut es nur, wenn der Hash-Code zuerst benötigt wird, und dann wird es zwischengespeichert (da Strings unveränderlich sind, ändert sich dieser Wert nicht).

Beachten Sie jedoch Effective Java 2nd Edition, Item 71: Verwenden Sie fazziöse Initialisierung mit Bedacht . Lazy-Initialisierung kann zu kleinen Fehlern führen und führt nicht immer zu einer verbesserten Leistung, die die zusätzliche Komplexität rechtfertigt. Nicht vorzeitig optimieren.

    
polygenelubricants 03.06.2010, 06:01
quelle
1

Konstruktoren sind insofern etwas Besonderes, als eine unbehandelte Ausnahme in einem Konstruktor seltsame Nebenwirkungen haben kann. Ohne Ihren Code zu sehen, würde ich annehmen, dass ein langer Konstruktor das Risiko von Ausnahmen erhöht. Ich würde den Konstruktor so einfach wie nötig machen und andere Methoden verwenden, um den Rest zu erledigen, um eine bessere Fehlerbehandlung zu ermöglichen.

    
Brian Rasmussen 03.06.2010 06:01
quelle
1

Der größte Nachteil ist wahrscheinlich der gleiche wie beim Schreiben einer anderen langen Funktion - dass sie komplex und schwer zu verstehen sein kann.

Der Rest wird variieren. Zuallererst korrelieren Länge und Ausführungszeit nicht unbedingt - Sie könnten eine einzelne Zeile (z. B. Funktionsaufruf) haben, die mehrere Sekunden dauerte (z. B. eine Verbindung zu einem Server herzustellen) oder eine Menge Code, der vollständig innerhalb der CPU und fertig schnell.

Die Startzeit wird (offensichtlich) nur von Konstruktoren beeinflusst, die beim Start aufgerufen wurden / werden. Ich habe in keinem Code, den ich geschrieben habe, ein Problem damit gehabt (zumindest vor kurzem), aber ich habe Code gesehen, der das getan hat. Bei einigen Arten von eingebetteten Systemen (für ein Beispiel) möchten Sie wirklich vermeiden, Objekte während der normalen Verwendung zu erstellen und zu zerstören, so dass Sie während des Systemstarts fast alles statisch erstellen. Sobald es läuft, können Sie alle Prozessorzeit widmen, um die eigentliche Arbeit zu erledigen.

    
Jerry Coffin 03.06.2010 06:07
quelle
0

Konstruktor ist noch eine weitere Funktion. Sie benötigen sehr lange Funktionen, die oft aufgerufen werden, damit das Programm langsam arbeitet. Wenn es also nur einmal aufgerufen wird, ist es normalerweise egal, wie viel Code darin ist.

    
sharptooth 03.06.2010 05:59
quelle
0

Es beeinflusst natürlich die Zeit, die es braucht, um dieses Objekt zu konstruieren, aber nicht mehr als einen leeren Konstruktor zu haben und Methoden aufzurufen, um das zu tun. Es hat keine Auswirkung auf die Anwendungsladezeit

    
Michael Mrozek 03.06.2010 06:00
quelle
0

Im Fall des Kopierkonstruktors verwenden wir in diesem Fall keine Referenz es wird ein Objekt erstellen und den Kopierkonstruktor aufrufen und das übergeben Wert für den Kopierkonstruktor und jedes Mal, wenn ein neues Objekt erstellt wird und jedes Mal, wenn es den Kopierkonstruktor aufrufen wird, geht es nach unendlich und füllen Sie den Speicher, dann zeigt es die Fehlermeldung an.

Wenn wir die Referenz übergeben, wird das neue Objekt zum Speichern nicht erstellt der Wert. und keine Rekursion wird stattfinden

    
bachchan 03.06.2010 06:01
quelle
0

Ich würde vermeiden, etwas in Ihrem Konstruktor zu tun, das nicht absolut notwendig ist. Initialisiere deine Variablen dort und versuche, nicht viel anderes zu tun. Weitere Funktionen sollten sich in separaten Funktionen befinden, die Sie nur bei Bedarf aufrufen.

    
Ben Burnett 03.06.2010 06:03
quelle

Tags und Links