C # -Konstrukteurentwurf

7

Ich habe eine Klasse, die Sie in einem Ordner übergeben und dann geht es ab und verarbeitet eine Menge Daten innerhalb des angegebenen Ordners.

Zum Beispiel:

%Vor%

Nun, was es tut, geht es los und liest ein paar tausend Dateien und füllt die Klasse mit Daten.

Sollte ich diese Daten aus dem Konstruktor verschieben und als separate Methode verwenden, wie zum Beispiel:

%Vor%     
Coding Monkey 08.06.2009, 05:35
quelle

9 Antworten

22

Vielleicht sollten Sie es auf diese Weise mit einer statischen Methode versuchen, die eine Instanz des Objekts zurückgibt.

%Vor%

Dies hält den Initialisierungscode außerhalb Ihres Konstruktors und gibt Ihnen die "one line" -Deklaration, nach der Sie suchen.

Gehen Sie auf den Kommentar von unten aus dem Poster, indem Sie State eine Implementierung hinzufügen könnte wie folgt:

%Vor%     
Tom Anderson 08.06.2009, 05:57
quelle
5

Es kommt darauf an. Sie sollten den grundlegenden Zweck der Klasse bewerten. Welche Funktion führt es aus?

Was ich normalerweise bevorzuge ist, dass ein Klassenkonstruktor die Initialisierung durchführt, die für das Funktionieren der Klasse notwendig ist. Dann rufe ich Methoden für die Klasse auf, die sicher annehmen können, dass die notwendige Initialisierung durchgeführt wurde.

In der Regel sollte die Initialisierungsphase nicht zu intensiv sein. Ein alternativer Weg, um das oben genannte zu tun, könnte sein:

%Vor%     
Cerebrus 08.06.2009 05:43
quelle
1

Ist das alles, was Ihre Klasse tut? Wenn ja, würde ich sagen, dass es nicht wirklich wichtig ist. Aber es ist wahrscheinlich, dass deine Klasse mehr tut als das, was du gezeigt hast. Hat es zum Beispiel eine Fehlerbehandlung?

Der Zweck des Konstruktors besteht darin, ein Objekt zu konstruieren. Der Zweck einer Methode besteht darin, eine Aktion auszuführen. Also meine Stimme ist für dieses Formular:

%Vor%     
Robert Harvey 08.06.2009 05:41
quelle
1

Ich stimme Ari und anderen zu - teile sie auf.

Ein Konstruktor sollte wirklich ein Minimum an Arbeit leisten (initialisieren Sie das Objekt einfach und lassen Sie es dabei). Mit einer separaten Methode, um die Arbeit zu erledigen:

  • Es ist für den Aufrufer klarer, dass die Worker-Funktion sehr lange dauern kann.
  • Es ist einfach, mehrere Konstruktoren zur Verfügung zu stellen, um das Objekt mit anderen Informationen zu initialisieren (zB können Sie eine eigene Klasse (statt einer Zeichenfolge) übergeben, die den Pfadnamen liefern kann. Oder Sie könnten einen zusätzlichen Parameter übergeben Gibt einen passenden Wildcards-Dateinamen an oder ein Flag, um anzugeben, ob die Suche in Unterordnern rekursiv sein soll.)
  • Sie vermeiden Probleme mit dem Konstruktor. Im Konstruktor ist das Objekt nicht vollständig ausgebildet, so dass es gefährlich sein kann, Arbeit zu leisten - z. Eine virtuelle Funktion innerhalb eines Konstruktors aufzurufen, ist eine sehr schlechte Idee. Je weniger Code Sie in den Konstruktor eingeben, desto weniger wahrscheinlich ist es, dass Sie aus Versehen etwas "Schlechtes" tun.
  • Es ist sauberer Codierungsstil, um verschiedene Verhaltensweisen / Funktionen in separate Methoden zu trennen. Halten Sie die Initialisierung und die Arbeit getrennt von
  • Eine Split-Klasse wird in Zukunft leichter zu pflegen und zu refaktorieren sein.
Jason Williams 08.06.2009 07:19
quelle
0

Wenn dies die einzige Ressource ist, mit der die Klasse arbeitet, wäre es wahrscheinlich besser, den Pfad zum Konstruktor zu übergeben. Andernfalls wäre es ein Parameter für Ihre Klassenmitglieder.

    
Sergey 08.06.2009 06:14
quelle
0

Meine persönliche Vorliebe wäre, C # 3.0-Initialisierer zu verwenden.

%Vor%

Dies hat einige Vorteile:

  • Objekt Instanziierung wird kein haben automatischer Nebeneffekt des Dateisystems.
  • Alle Argumente sind benannt.
  • Alle Argumente sind optional (aber natürlich könnte ein werfen Ausnahme in Load (), falls nicht definiert)
  • Sie können so viele Eigenschaften wie Sie initialisieren will im Instantiierungsaufruf ohne überladen zu müssen Konstrukteur. Zum Beispiel, Optionen ob man Verzeichnisse rekursiv oder ein Platzhalter für die zu suchende Dateispezifikation für.
  • Sie könnten immer noch etwas Logik haben im Setter für das Verzeichnis zu tun einige Sachen, aber wieder, Nebenwirkungen sind normalerweise keine gute Sache.
  • Durch Ausführen von Dateioperationen in a separaten Prozeduraufruf, vermeiden Sie das Problem nicht zu können referenzieren Sie Ihre myClass-Instanz in der Ausnahmebehandler.
richardtallent 08.06.2009 06:32
quelle
0

Ich werde die Leute hier "aufteilen". Wenn es hilft, versuchen Sie Folgendes:

  1. Fragen Sie sich: "Was macht diese Methode / Eigenschaft / Feld ?"
  2. Lass es geschehen; nicht mehr und nicht weniger.

Wenn Sie das hier anwenden, erhalten Sie Folgendes:

  1. Der Konstruktor soll das Objekt erstellen.
  2. Ihre Methode soll ihre Daten aus dem Dateisystem laden.

Das scheint mir logischer zu sein als "Der Konstruktor soll das Objekt erstellen und seine Daten aus dem Dateisystem laden.

    
Ari Roth 08.06.2009 07:09
quelle
0

Ich denke, Sie sollten sich zwischen den zwei oben genannten Ansätzen ("zuerst initialisieren, dann ausführen" vs. "leeres init, mit params ausführen") entscheiden, je nachdem, ob Sie dasselbe Objekt erneut verwenden möchten, um dieselbe Operation an einer anderen Eingabe auszuführen .
Wenn die Klasse nur verwendet wird, um die Aufgabe mit einem festen Parameter auszuführen, würde ich sie im Konstruktor initialisieren (so dass sie gerade gelesen wird) und dann die Aufgabe auf einer anderen Methode ausführen.
Wenn Sie die Aufgabe weiterhin für verschiedene Parameter ausführen möchten, würde ich sie in die Task-Methode selbst einfügen.

Wenn die Klasse diese Aufgabe ausführt, würde ich auch alles in eine statische Klasse / Methoden ändern - sie muss ihren internen Status nicht behalten.

Wie auch immer, ich würde niemals die Aufgabe selbst in den Konstruktor einfügen. Wie Cerebrus sagte, sollte die Initialisierung schnell sein.

    
Noam Gal 08.06.2009 06:02
quelle
0

Wenn der Hauptzweck Ihrer Klasse nicht die Ausführung von I / O ist, sollten Sie wahrscheinlich keine I / O-Operationen (möglicherweise eine IOException) im Konstruktor ausführen.

Ziehen Sie in Betracht, die Klasse in zwei Teile aufzuteilen:

%Vor%

Auf diese Weise kann sich die Hauptklasse auf die Verwaltung ihres eigenen Zustands konzentrieren, während die Datenquelle den Anfangszustand aus dem Dateiinhalt erstellt.

    
finnw 08.06.2009 06:09
quelle

Tags und Links