Sind optionale Parameter, wie sie in C # verwendet werden, hilfreich oder behindern sie die Anwendungswartung und sollten vermieden werden, da sie das Verständnis des Codes erschweren können?
Sind optionale Parameter, wie sie in C # verwendet werden, hilfreich oder behindern sie die Anwendungswartung und sollten vermieden werden, da sie das Verständnis des Codes erschweren können?
Antworten:
Optionale Parameter waren meiner Erfahrung nach eine gute Sache. Ich habe sie nie verwirrend gefunden (zumindest nicht verwirrender als die eigentliche Funktion), da ich immer die Standardwerte abrufen kann und weiß, wie sie heißen.
Eine Verwendung für sie ist, wenn ich einer Funktion, die bereits allgemein verwendet wird, oder zumindest in der öffentlichen Schnittstelle, einen weiteren Parameter hinzufügen muss. Ohne sie müsste ich die ursprüngliche Funktion wiederholen, um eine Funktion aufzurufen, die ein anderes Argument enthält, und das kann sehr alt werden, wenn ich mehr als einmal Argumente hinzufüge.
new Circle(size, color, filled, ellipseProportions)
wo size
und color
erforderlich sind, und der Rest ist Standard.
Wenn Sie häufig viele / optionale Parameter benötigen, tun Ihre Funktionen im Allgemeinen zu viel und sollten getrennt werden. Sie brechen wahrscheinlich SRP (Single Responsibility Principle).
Suchen Sie nach Parametern, die gruppiert werden können, z. B. (x und y werden zu einem Punkt).
Sind diese optionalen Parameter-Flags voreingestellt? Wenn Sie Flags verwenden, sollte die Funktion aufgeteilt werden.
Das heißt nicht, dass Sie niemals optionale Parameter haben sollten, aber im Allgemeinen deuten mehr als ein oder zwei Parameter auf einen Codegeruch hin.
Es könnte auch ein Hinweis sein, dass die Funktion tatsächlich eine Klasse sein sollte, wobei die optionalen Parameter in Eigenschaften geändert wurden und der erforderliche Parameterteil des Konstruktors.
Optionale Parameter sind in Ordnung
In der Regel lautet die Rechtfertigung entweder: a) Sie wissen, dass Sie viele mögliche Argumente für Ihre Methode haben, aber aus Angst, Ihre API zu überladen, nicht möchten, oder b) Sie kennen nicht alle möglichen Argumente außer Ihnen Sie möchten Ihren Benutzer nicht zwingen, ein Array bereitzustellen. In jedem Fall retten optionale Parameter auf elegante Art und Weise.
Hier sind einige Beispiele:
1. Sie möchten eine Überlastung vermeiden und möchten kein Array angeben
Schauen Sie sich printf () von C, Perl, Java usw. an. Es ist ein großartiges Beispiel für die Leistungsfähigkeit optionaler Parameter.
Beispielsweise:
printf("I want %d %s %s",1,"chocolate","biccies");
printf("I want %d banana",1);
Keine Überladung, keine Arrays, einfach und intuitiv (sobald Sie die Standard-String-Format-Codes verstanden haben). Einige IDEs teilen Ihnen sogar mit, ob Ihre Formatzeichenfolge nicht Ihren optionalen Parametern entspricht.
2. Sie möchten die Verwendung von Standardeinstellungen zulassen und diese für den Benutzer der Methode verborgen halten
sendEmail ("test@example.org");
Die sendEmail-Methode erkennt, dass verschiedene wichtige Werte fehlen, und füllt sie mit definierten Standardwerten (Betreff, Text, CC, BCC usw.). Die API bleibt sauber und dennoch flexibel.
Ein Hinweis auf zu viele Parameter
Wie andere bereits festgestellt haben, deutet eine zu große Anzahl von obligatorischen Parametern für eine Methode darauf hin, dass möglicherweise ein Fehler in Ihrem Entwurf vorliegt. Dies gilt insbesondere dann, wenn sie denselben Typ haben, da sie vom Entwickler versehentlich gewechselt werden können, was zur Laufzeit zu merkwürdigen Ergebnissen führt:
String myMethod(String x, String y, String z, String a, int b, String c, int d) {}
ist ein idealer Kandidat für das Refactoring von Introduce Parameter Object
String myMethod(ParameterObject po) {}
class ParameterObject {
// Left as public for clarity
public String x;
public String y;
... etc
}
Dies kann wiederum zu einem besseren Design führen, das auf einem Factory-Muster mit einer bereitgestellten Spezifikation als Parameterobjekt basiert.
Eines der Probleme mit Standardparametern in C # (ich denke, DoSomething ist ungültig (int x = 1)) sind Konstanten. Das heißt, wenn Sie die Standardeinstellung ändern, müssen Sie alle Konsumenten dieses Methodenaufrufs neu kompilieren. Dies ist zwar einfach genug, aber es gibt Situationen, in denen dies gefährlich ist.
Es hängt davon ab, was Ihr Code tut. Wenn es sinnvolle Standardeinstellungen gibt, sollten Sie optionale Parameter verwenden. Wenn es jedoch keine sinnvollen Standardeinstellungen gibt, wird der Code durch Hinzufügen optionaler Parameter komplizierter. In vielen Fällen sind optionale Parameter eine gute Möglichkeit, Nullprüfungen zu umgehen und die Verzweigungslogik zu umgehen. Javascript hat keine optionalen Parameter, aber es gibt eine Möglichkeit, sie mit || zu emulieren (logisch oder) und ich benutze es die ganze Zeit, wenn ich datenbankbezogene Dinge mache, denn wenn der Benutzer keinen Wert angibt, dann ersetze ich meine eigenen Werte mit Hilfe von || Das erspart mir die Mühe, eine ganze Reihe von if then-Anweisungen zu schreiben.
Optionale Parameter sind eine großartige Möglichkeit, um einfache und komplizierte Dinge gleichzeitig zu ermöglichen. Wenn die meisten Benutzer, zumindest in schnellen und unsauberen Anwendungsfällen, eine eindeutige vernünftige Vorgabe wünschen, sollten sie nicht jedes Mal, wenn sie Ihre Funktion aufrufen, ein Boilerplate schreiben müssen, um es manuell anzugeben. Auf der anderen Seite, wenn die Leute einen guten Grund haben, es ändern zu wollen, dann muss es aufgedeckt werden.
Die Verwendung einer Klasse ist meiner Meinung nach eine schreckliche Lösung, da sie wortreich, ineffizient und im Widerspruch zum typischen mentalen Modell dessen steht, was eine Klasse tut. Eine Funktion ist die perfekte Abstraktion für ein Verb, dh etwas tun und zurückkehren. Eine Klasse ist die richtige Abstraktion für ein Substantiv, dh etwas, das einen Zustand hat und auf verschiedene Arten manipuliert werden kann. Wenn Ersteres das mentale Modell des API-Benutzers sein soll, dann machen Sie es nicht zu einer Klasse.
Das Problem mit optionalen Argumenten ist, dass die Leute dazu neigen, immer mehr (und mehr) Argumente für die Funktion zu verwenden, anstatt relevanten Code in eine neue Funktion zu extrahieren. Dies wird in PHP auf das Äußerste getrieben . Zum Beispiel:
bool array_multisort ( array &$arr [, mixed $arg = SORT_ASC
[, mixed $arg = SORT_REGULAR [, mixed $... ]]] )
Ich habe dieses Feature in Python anfangs geliebt und es verwendet, um bereits verwendete Methoden zu erweitern. Und es sah nett und einfach aus, aber es kehrte bald zurück; Denn als ich einen optionalen Parameter hinzufügte, änderte dies das Verhalten einer vorhandenen Methode, auf die sich der alte Client stützte, und auf eine Weise, die von vorhandenen Unit-Testfällen nicht erfasst wurde. Im Grunde bedeutet dies, das Open Closed-Prinzip zu brechen. Code ist zur Erweiterung offen, aber zur Änderung geschlossen. Daher halte ich es nicht für eine gute Idee, diese Funktion zum Ändern des vorhandenen Codes zu verwenden. aber okay, wenn von Anfang an verwendet
Ich denke, es wäre besser, eine Funktion mit anderen Signaturen (dh Parametern) zu überladen, als optionale Parameter zu verwenden.