Ich habe diese API-Funktion:
public ResultEnum DoSomeAction(string a, string b, DateTime c, OtherEnum d,
string e, string f, out Guid code)
Ich mag es nicht Weil die Parameterreihenfolge unnötig wichtig wird. Es wird schwieriger, neue Felder hinzuzufügen. Es ist schwieriger zu sehen, was herumgereicht wird. Es ist schwieriger, die Methode in kleinere Teile umzugestalten, da dadurch ein weiterer Aufwand für die Übergabe aller Parameter in Unterfunktionen entsteht. Code ist schwerer zu lesen.
Ich hatte die naheliegendste Idee: Lassen Sie ein Objekt die Daten kapseln und weitergeben, anstatt jeden Parameter einzeln zu übergeben. Folgendes habe ich mir ausgedacht:
public class DoSomeActionParameters
{
public string A;
public string B;
public DateTime C;
public OtherEnum D;
public string E;
public string F;
}
Das reduzierte meine API-Deklaration auf:
public ResultEnum DoSomeAction(DoSomeActionParameters parameters, out Guid code)
Nett. Sieht sehr unschuldig aus, aber wir haben tatsächlich eine große Veränderung eingeführt: Wir haben die Veränderlichkeit eingeführt. Denn was wir zuvor getan hatten, war tatsächlich, ein anonymes unveränderliches Objekt zu übergeben: Funktionsparameter auf dem Stapel. Jetzt haben wir eine neue Klasse erstellt, die sehr veränderlich ist. Wir haben die Möglichkeit geschaffen, den Status des Anrufers zu manipulieren . Das ist Scheiße. Jetzt möchte ich mein Objekt unveränderlich, was mache ich?
public class DoSomeActionParameters
{
public string A { get; private set; }
public string B { get; private set; }
public DateTime C { get; private set; }
public OtherEnum D { get; private set; }
public string E { get; private set; }
public string F { get; private set; }
public DoSomeActionParameters(string a, string b, DateTime c, OtherEnum d,
string e, string f)
{
this.A = a;
this.B = b;
// ... tears erased the text here
}
}
Wie Sie sehen, habe ich mein ursprüngliches Problem tatsächlich neu erstellt: zu viele Parameter. Es ist offensichtlich, dass dies nicht der richtige Weg ist. Was soll ich tun? Die letzte Möglichkeit, eine solche Unveränderlichkeit zu erreichen, besteht darin, eine "schreibgeschützte" Struktur wie diese zu verwenden:
public struct DoSomeActionParameters
{
public readonly string A;
public readonly string B;
public readonly DateTime C;
public readonly OtherEnum D;
public readonly string E;
public readonly string F;
}
Dadurch können wir Konstruktoren mit zu vielen Parametern vermeiden und Unveränderlichkeit erreichen. Eigentlich behebt es alle Probleme (Parameterreihenfolge usw.). Noch:
- Alle (einschließlich FXCop & Jon Skeet) sind sich einig, dass die Offenlegung öffentlicher Felder schlecht ist .
- Eric Lippert et al. Sagen, es sei eine Lüge , sich für die Unveränderlichkeit auf schreibgeschützte Felder zu verlassen .
In diesem Moment war ich verwirrt und beschloss, diese Frage zu schreiben: Was ist der einfachste Weg in C #, um das Problem "zu vieler Parameter" zu vermeiden, ohne die Veränderlichkeit einzuführen? Ist es möglich, eine schreibgeschützte Struktur für diesen Zweck zu verwenden und dennoch kein schlechtes API-Design zu haben?
ERKLÄRUNGEN:
- Bitte nehmen Sie an, dass kein Verstoß gegen das Prinzip der Einzelverantwortung vorliegt. In meinem ursprünglichen Fall schreibt die Funktion nur bestimmte Parameter in einen einzelnen DB-Datensatz.
- Ich suche keine spezifische Lösung für die gegebene Funktion. Ich suche einen allgemeinen Ansatz für solche Probleme. Ich bin speziell daran interessiert, das Problem "zu viele Parameter" zu lösen, ohne die Veränderlichkeit oder ein schreckliches Design einzuführen.
AKTUALISIEREN
Die hier gegebenen Antworten haben unterschiedliche Vor- und Nachteile. Deshalb möchte ich dies in ein Community-Wiki konvertieren. Ich denke, jede Antwort mit Codebeispiel und Vor- / Nachteilen wäre ein guter Leitfaden für ähnliche Probleme in der Zukunft. Ich versuche jetzt herauszufinden, wie es geht.
DoSomeActionParameters
es sich um ein Wegwerfobjekt handelt, das nach dem Methodenaufruf verworfen wird.