Sollte die Erstellung eines Objekts implizit oder explizit eine Datei erstellen?

9

Ich erstelle ein Objekt, dessen einziger Zweck darin besteht, eine Datei eines Formats einzulesen und eine andere Datei eines anderen Formats zu erstellen.

Ist es am besten, die Ausgabedatei implizit während der Objektinitialisierung zu erstellen oder über eine öffentliche Methode zu verfügen, mit der der Benutzer auswählen kann, wann diese Datei erstellt werden soll?

PDStat
quelle

Antworten:

12

Wenn Sie in einer Sprache arbeiten, die dies unterstützt, würde ich eine Speichermethode bereitstellen, die einen Stream verwendet. Auf diese Weise kann der Benutzer die Daten speichern, wo immer er möchte.

Das Schreiben dauert 20 Sekunden länger als das Speichern nur in einer Datei, ist jedoch für einen Programmierer leicht verständlich, und an der aufrufenden Site ist sehr klar, was tatsächlich passiert.

Die Art und Weise, wie Sie es beschrieben haben (ein Objekt, das Eingaben liest und in eine andere Datei ausgibt), erscheint ansonsten seltsam. Was ist der Zweck, ein Objekt zu konstruieren, das während der Konstruktion alles macht?

Würden Sie es so nennen?

var stuff = DoStuff();
new SaveFileWeirdClass(stuff);
return;

Für eine vernünftige Implementierung von SaveFileWeirdClass würde ich keine Nebenwirkungen erwarten, wenn ich es nur erstelle. Eine Datei lesen - gut. Eine Datei erstellen? Nein.

Mir scheint es so klarer:

var stuff = new StuffReader(); //Better name needed...
string filePath = this.whatever;

using(Stream stream = new FileStream(filePath))
    stuff.Save(stream);
Max
quelle
1
Das ist gut. Eine andere, ähnliche Option besteht darin, einfach ein Objekt zu implementieren, das die Stream-Basis der Anwendung implementiert, und es wie jeden anderen Stream zu behandeln.
Steven Evers
3

Wenn Sie dies in der Klasse tun möchten, erstellen Sie es während der Initialisierung. Das Verzögern dieses Schritts führt zu zwei schlechten Dingen: Erstens wird ein zusätzlicher expliziter Schritt für den Aufrufer hinzugefügt, der das Objekt überhaupt nicht erstellt hätte, wenn er nicht beabsichtigt hätte, es zur Erzeugung der Ausgabe zu verwenden. Zweitens werden mindestens zwei Punkte hinzugefügt, an denen der Code in der Klasse entscheiden muss, ob die Datei geöffnet ist oder nicht, und diese Bedingung behandelt: einmal beim Schreiben der Ausgabe und einmal während der Zerstörung beim Schließen. Ersteres bedeutet, dass Sie diese Überprüfung bei jedem Schreiben durchführen müssen, was verschwenderisch sein kann, wenn Sie viele davon ausführen.

Persönlich würde ich beides nicht tun und mich dafür entscheiden, dass der Anrufer vorgeöffnete Dateihandles an den Konstruktor übergibt. Das Erstellen der Datei innerhalb der Klasse schließt aus, dass den Anrufern die Möglichkeit gegeben wird, beispielsweise Berechtigungen festzulegen oder beim Schreiben auf ein Gerät eine gerätespezifische Initialisierung durchzuführen. Wenn Sie eine Version Ihrer FooConverterKlasse haben möchten, die Dateien verarbeitet und das Erstellungsgrunzen ausführt, verpacken Sie sie in a FooFileConverter.

Blrfl
quelle
2

Ausdrücklich.

Sie möchten sicherstellen, dass Sie sich nicht auf clevere Nebenwirkungsregeln verlassen, die in zukünftigen Versionen oder in ungewöhnlichen Architekturen möglicherweise nicht funktionieren. Natürlich sollten Sie eine Standarddatei haben, die der Benutzer überschreiben kann, wenn er dies wünscht.

Sardathrion - gegen SE-Missbrauch
quelle
1

Zusätzlich zu den anderen Argumenten für eine explizite Methode: Wenn Sie die Arbeit im Konstruktor ausführen, zwingen Sie jeden Benutzer Ihrer Klasse, die Ausnahmebehandlung nur zum Erstellen des Objekts durchzuführen. Dies kann zu viel Code auf dem Boilerplate führen.

Eine Diskussion darüber finden Sie unter /programming/6086334/is-it-good-practice-to-make-the-constructor-throw-an-exception .

Bananeweizen
quelle