Manchmal müssen Sie einen Konstruktor schreiben, der fehlschlagen kann. Angenommen, ich möchte ein Objekt mit einem Dateipfad instanziieren
obj = new Object("/home/user/foo_file")
Solange der Pfad auf eine entsprechende Datei verweist, ist alles in Ordnung. Aber wenn die Zeichenfolge kein gültiger Pfad ist, sollten die Dinge kaputt gehen. Aber wie?
Du könntest:
- eine Ausnahme auslösen
- Rückgabe des Nullobjekts (wenn Ihre Programmiersprache es Konstruktoren erlaubt, Werte zurückzugeben)
- ein gültiges Objekt zurückgeben, aber mit einem Flag, das angibt, dass sein Pfad nicht richtig gesetzt wurde (ugh)
- Andere?
Ich gehe davon aus, dass die "Best Practices" verschiedener Programmiersprachen dies unterschiedlich implementieren würden. Zum Beispiel denke ich, dass ObjC (2) bevorzugt. Es wäre jedoch unmöglich, (2) in C ++ zu implementieren, wo Konstruktoren void als Rückgabetyp haben müssen. In diesem Fall gehe ich davon aus, dass (1) verwendet wird.
Können Sie in der Programmiersprache Ihrer Wahl zeigen, wie Sie mit diesem Problem umgehen würden, und erklären, warum?
quelle
void
- sie geben ein Objekt zurück.new
ruftoperator new
auf, um den Speicher zuzuweisen, und dann den Konstruktor, um ihn zu füllen. Der Konstruktor gibt nichts zurück undnew
gibt den Zeiger zurück, von dem er erhalten hatoperator new
. Ob "nichts zurückgibtvoid
" impliziert, dass "zurückgibt ", ist jedoch zu gewinnen.Antworten:
Es ist nie gut, sich auf einen Konstrukteur zu verlassen, um die Drecksarbeit zu erledigen. Außerdem ist einem anderen Programmierer auch unklar , ob im Konstruktor gearbeitet werden soll oder nicht, es sei denn, es gibt eine explizite Dokumentation, die dies angibt (und die Benutzer der Klasse haben sie gelesen oder wurden dazu aufgefordert).
Zum Beispiel (in C #):
Was passiert, wenn der Benutzer die Datei nicht sofort laden möchte? Was ist, wenn die Datei bei Bedarf zwischengespeichert werden soll? Sie können nicht. Sie könnten überlegen, ein
bool loadFile
Argument in den Konstruktor einzufügen, aber dies macht dies unübersichtlich, da Sie jetzt noch eineLoad()
Methode zum Laden der Datei benötigen .Angesichts des aktuellen Szenarios wird es für die Benutzer der Klasse flexibler und klarer, dies zu tun:
Oder alternativ (für so etwas wie eine Ressource):
quelle
In Java können Sie Ausnahmen verwenden oder das Factory-Muster verwenden, mit dem Sie null zurückgeben können.
In Scala können Sie eine Option [Foo] von einer Factory-Methode zurückgeben. Das würde auch in Java funktionieren, wäre aber umständlicher.
quelle
Eine Ausnahme auslösen.
Null muss überprüft werden, wenn Sie es zurückgeben können (und es wird nicht überprüft)
Dafür gibt es geprüfte Ausnahmen. Sie wissen, dass es scheitern könnte. Anrufer müssen damit umgehen.
quelle
In C ++ werden Konstruktoren verwendet, um Mitglieder der Klasse zu erstellen / zu initialisieren.
Es gibt keine richtige Antwort auf diese Frage. Was ich bisher beobachtet habe, ist, dass meistens der Client (oder derjenige, der Ihre API verwenden wird) entscheidet, wie Sie mit diesen Dingen umgehen sollen.
Manchmal könnten sie Sie bitten , alle Ressourcen , das Objekt muss möglicherweise auf den Konstruktor zuweisen und werfen eine Ausnahme , wenn etwas fehlschlägt (die Erstellung des Objekts abgebrochen) oder tun nichts davon auf den Konstruktor, und stellen Sie sicher , dass die Schöpfung immer erfolgreich Überlassen Sie diese Aufgaben einigen Mitgliedsfunktionen.
Wenn Sie das Verhalten auswählen müssen, sind Ausnahmen die Standardmethode für die Behandlung von Fehlern in C ++, und Sie sollten sie verwenden, wenn Sie können.
quelle
Sie können das Objekt auch ohne Parameter oder nur mit Parametern instanziieren, die sicher niemals ausfallen werden, und dann eine Initialisierungsfunktion oder -methode verwenden, mit der Sie sicher eine Ausnahme auslösen oder tun können, was Sie möchten.
quelle
Ich bevorzuge es, keine Klasse oder Liste im Konstruktor zu initialisieren. Initialisieren Sie eine Klasse oder Liste, wann immer Sie möchten. Z.B.
Tu das nicht
Initialisieren Sie stattdessen bei Bedarf, z.
quelle