Aus einigen Open Source-Projekten habe ich den folgenden Codierungsstil zusammengetragen
void someFunction(bool forget);
void ourFunction() {
someFunction(false /* forget */);
}
Ich habe immer Zweifel, was false
hier bedeutet. Bedeutet es "vergessen" oder bezieht sich das "vergessen" auf den entsprechenden Parameter (wie im obigen Fall) und "falsch" soll es negieren?
Welcher Stil wird am häufigsten verwendet und wie lässt sich die Mehrdeutigkeit am besten (oder auf eine der besseren Arten) vermeiden?
coding-style
comments
boolean
Johannes Schaub - litb
quelle
quelle
someFunction(forget: true);
true
zufalse
und nicht den Kommentar aktualisieren. Wenn Sie die API nicht ändern können, ist dies am besten zu kommentierensomeFunction( false /* true=forget, false=remember */)
sortAscending
undsortDescending
oder ähnlich). Nun, nach innen , können sie rufen beide die gleiche private Methode, die diese Art von Parametern haben könnte. Wenn die Sprache dies unterstützen würde, wäre das, was ich übergeben würde, wahrscheinlich eine Lambda-Funktion, die die Sortierrichtung enthält ...Antworten:
In dem von Ihnen geposteten Beispielcode sieht es so aus, als ob
forget
es sich um ein Flag-Argument handelt. (Ich kann nicht sicher sein, weil die Funktion rein hypothetisch ist.)Flag-Argumente sind ein Codegeruch. Sie zeigen an, dass eine Funktion mehr als eine Sache tut und eine gute Funktion nur eine Sache tun sollte.
Teilen Sie die Funktion zur Vermeidung des Flags in zwei Funktionen auf, die den Unterschied im Funktionsnamen erklären.
Flag Argument
Kein Flag-Argument
edit: Im Idealfall müssen Sie eine Funktion mit dem Flag-Parameter überhaupt nicht beibehalten. Es gibt Fälle in der Art, wie Fowler eine verworrene Implementierung nennt, bei der eine vollständige Trennung der Funktionen zu doppeltem Code führt. Je höher jedoch die zyklomatische Komplexität der parametrisierten Funktion ist, desto stärker ist das Argument, sie loszuwerden.
Dies ist nur eine Vermutung, aber ein Parameter namens
forget
klingt wie Feature-Neid. Warum sollte ein Anrufer einem anderen Objekt mitteilen, dass es etwas vergessen soll? Möglicherweise liegt ein größeres Designproblem vor.quelle
serveTraditionalIceCream
undserveLowFatIceCream
wie sehen sie aus? Ich habe eine Aufzählung von 14 Eissorten.Mit den Worten des Laien:
false
ist ein wörtliches.false
someFunction
, nicht zu vergessensomeFunction
dass der Parameter vergessen istfalse
someFunction
zu erinnernMeiner Meinung nach wäre es besser, wenn die Funktion so wäre:
das kannst du so nennen
oder behalten Sie den alten Namen bei, ändern Sie jedoch Ihre Wrapper-Funktion in
BEARBEITEN:
Wie @Vorac sagte, bemühen Sie sich immer, positive Wörter zu verwenden. Doppelte Verneinung ist verwirrend.
quelle
remember
, es sei denn, der Funktionsname hat die Bedeutung vonremember
sehr offensichtlich gemacht.rememberToCleanUp* or *persist
oder so.Der Parameter kann einen guten Namen haben. es ist schwer zu sagen, ohne den Namen der Funktion zu kennen. Ich gehe davon aus, dass der Kommentar von den ursprünglichen Autor der Funktion geschrieben wurde, und es war eine Erinnerung daran, was vorbei
false
insomeFunction
Mittel, sondern auch für alle später kommen zusammen, es ist ein wenig unklar , auf den ersten Blick.Die Verwendung eines positiven Variablennamens (vorgeschlagen in Code Complete ) ist möglicherweise die einfachste Änderung, die das Lesen dieses Snippets erleichtert, z
dann
ourFunction
wird:Durch die Verwendung einer Aufzählung wird der Funktionsaufruf jedoch auf Kosten eines unterstützenden Codes noch verständlicher:
Wenn Sie die Signatur aus
someFunction
irgendeinem Grund nicht ändern können , vereinfacht die Verwendung einer temporären Variablen auch das Lesen des Codes, indem Sie eine Variable nur einführen, um den Code für den Menschen einfacher parsen zu können .quelle
remember
true setzen bedeutet vergessen (in Ihrem Beispiel vonsomeFunction(true /* forget */);
)?enum
ist bei weitem die beste Lösung. Nur weil ein Typ kann als dargestellt werdenbool
-ie, sie sind isomorph-es bedeutet nicht , dass es sollte als solche dargestellt werden. Das gleiche Argument gilt fürstring
und sogarint
.Benennen Sie die Variable um, damit ein bool-Wert Sinn macht.
Dies ist millionenfach besser als das Hinzufügen eines Kommentars zur Erläuterung von Argumenten zu einer Funktion, da der Name nicht eindeutig ist.
quelle
Erstellen Sie einen lokalen Booleschen Wert mit einem aussagekräftigeren Namen und weisen Sie ihm den Wert zu. Auf diese Weise wird die Bedeutung klarer.
Wenn Sie die Variable nicht umbenennen können, sollte der Kommentar etwas aussagekräftiger sein:
quelle
/* forget */
Kommentar da ist, um es anzusprechen. Ohne die Funktionsdeklaration direkt vor Ihnen kann es schwierig sein, sich zu erinnern, worauf eingestellt wirdfalse
. (Aus diesem Grund denke ich, dass @ Esailijas Rat besser ist, eine Aufzählung hinzuzufügen, und warum ich Sprachen liebe, die benannte Parameter zulassen.)Es gibt einen guten Artikel, der genau diese Situation erwähnt, da er sich auf Qt-Style-APIs bezieht. Dort heißt es The Boolean Parameter Trap und es ist eine Lektüre wert.
Der Kern davon ist:
quelle
Dies ist ein bizarrer Kommentar.
Aus der Sicht des Compilers
someFunction(false /* forget */);
ist dies tatsächlichsomeFunction(false);
(der Kommentar wird entfernt). In dieser Zeile wird also nursomeFunction
das erste (und einzige) Argument aufgerufen, das auf gesetzt istfalse
./* forget */
ist nur der Name des Parameters. Es ist wahrscheinlich nichts weiter als eine schnelle (und schmutzige) Erinnerung, die nicht unbedingt da sein muss. Verwenden Sie einfach einen weniger mehrdeutigen Parameternamen, und Sie brauchen den Kommentar überhaupt nicht.quelle
Einer der Ratschläge von Clean Code ist, die Anzahl unnötiger Kommentare 1 zu minimieren (da sie zum Verrotten neigen) und Funktionen und Methoden richtig zu benennen.
Danach würde ich nur den Kommentar entfernen. Schließlich wird in modernen IDEs (wie Eclipse) ein Kästchen mit Code angezeigt, wenn Sie mit der Maus über die Funktion fahren. Das Sehen des Codes sollte die Mehrdeutigkeit beseitigen.
1 Das Kommentieren von komplexem Code ist in Ordnung.
quelle
Um das Offensichtliche zu beleuchten, können Kommentare lügen. So ist immer besser , um Ihren Code selbsterklärend, ohne auf die Kommentare zurückgreifen zu erklären, weil einige Menschen (vielleicht Sie) ändern
true
zufalse
und nicht den Kommentar aktualisieren.Wenn Sie die API nicht ändern können, greife ich auf zwei Optionen zurück
quelle
Mir gefällt die Antwort, dass der Kommentar immer wahr ist , aber obwohl er gut ist, vermisse ich das grundlegende Problem mit diesem Code - er wird mit einem Literal aufgerufen.
Sie sollten die Verwendung von Literalen beim Aufrufen von Methoden vermeiden. Lokale Variablen, optionale Parameter, benannte Parameter, Aufzählungen - wie Sie sie am besten vermeiden, hängt von der Sprache und den verfügbaren Informationen ab. Versuchen Sie jedoch, sie zu vermeiden. Literale haben Werte, aber sie haben keine Bedeutung.
quelle
In C # habe ich benannte Parameter verwendet, um dies zu verdeutlichen
Oder
enum
:Oder Überladungen:
Oder Polymorphismus`:
quelle
Die Benennung sollte immer die Mehrdeutigkeit für Boolesche Werte auflösen. Ich nenne Boolean immer so etwas wie 'isThis' oder 'shouldDoThat', zum Beispiel:
und so weiter. Wenn Sie jedoch auf den Code einer anderen Person verweisen, ist es am besten, beim Übergeben von Werten nur einen Kommentar zu hinterlassen.
quelle