Ich habe vor ein paar Wochen an einer Veranstaltung zum Thema Software-Handwerk teilgenommen, und einer der Kommentare lautete: "Ich bin sicher, wir alle erkennen schlechten Code, wenn wir ihn sehen."
Diese Art von Dingen beunruhigt mich immer, da es diese Binsenweisheit gibt, die jeder für einen überdurchschnittlichen Fahrer hält. Obwohl ich denke, dass ich schlechten Code erkennen kann, würde ich gerne mehr darüber erfahren, was andere Leute als Codegerüche betrachten, da dies in den Blogs der Leute selten und nur in einer Handvoll Büchern ausführlich besprochen wird. Insbesondere finde ich es interessant, etwas zu hören, das in einer Sprache nach Code riecht, aber nicht in einer anderen.
Ich beginne mit einem einfachen:
Code in der Quellcodeverwaltung mit einem hohen Anteil an auskommentiertem Code - warum ist er dort? sollte es gelöscht werden? ist es eine halbfertige Arbeit? Vielleicht hätte es nicht auskommentiert werden sollen und wurde nur gemacht, wenn jemand etwas ausprobierte? Persönlich finde ich solche Dinge wirklich ärgerlich, auch wenn es hier und da nur die eine oder andere Zeile ist, aber wenn Sie große Blöcke sehen, die mit dem Rest des Codes durchsetzt sind, ist das völlig inakzeptabel. Dies ist normalerweise auch ein Hinweis darauf, dass der Rest des Codes wahrscheinlich ebenfalls von zweifelhafter Qualität ist.
quelle
printf("%c", 7)
In der Regel läutet Alarmglocken für mich. ;)Antworten:
In der Regel in einem Quatschblock gefunden
try..catch
, neigt es dazu, meine Aufmerksamkeit zu erregen. Genau so gut wie/* Not sure what this does, but removing it breaks the build */
.Noch ein paar Dinge:
if
Anweisungenprocess
,data
,change
,rework
,modify
Eine habe ich gerade gefunden:
Richtig, weil es der richtige Weg ist, Ihre MySQL-Verbindungen brachial zu erzwingen. Es stellte sich heraus, dass die Datenbank Probleme mit der Anzahl der Verbindungen hatte, so dass das Zeitlimit konstant blieb. Anstatt dies zu debuggen, versuchten sie es einfach immer wieder, bis es funktionierte.
quelle
Die wichtigste rote Fahne für mich sind duplizierte Codeblöcke, da sie zeigen, dass die Person entweder die Programmiergrundlagen nicht versteht oder zu ängstlich war, um die richtigen Änderungen an einer vorhandenen Codebasis vorzunehmen.
Ich habe auch das Fehlen von Kommentaren als rote Fahne gewertet, aber nachdem ich in letzter Zeit eine Menge sehr guten Codes ohne Kommentare bearbeitet habe, habe ich das zurückgenommen.
quelle
Code, der zeigt, wie schlau der Programmierer ist, obwohl er keinen echten Mehrwert bietet:
quelle
swap(x, y);
^_^
20.000 (übertriebene) Zeilenfunktionen. Jede Funktion, die mehr als ein paar Bildschirme benötigt, muss neu faktorisiert werden.
In die gleiche Richtung gehen Klassendateien, die scheinbar ewig dauern. Es gibt wahrscheinlich einige Konzepte, die in Klassen abstrahiert werden könnten, um den Zweck und die Funktion der ursprünglichen Klasse zu klären, und wahrscheinlich, wo sie verwendet wird, es sei denn, es handelt sich ausschließlich um interne Methoden.
Nicht beschreibende, nicht triviale Variablen oder zu viele triviale, nicht beschreibende Variablen. Diese machen es zu einem Rätsel, was tatsächlich passiert.
quelle
Was noch schlimmer ist, ist das aus einer kommerziellen Bibliothek!
quelle
Kommentare, die so ausführlich sind, dass ein englischer Compiler zwar perfekt kompiliert und ausgeführt werden kann, jedoch nichts beschreibt, was der Code nicht beschreibt.
Bei Kommentaren zu Code, der hätte entfernt werden können, wurden einige grundlegende Richtlinien eingehalten:
quelle
/
von dem*/
fehlt, so dass der gesamte Code bis zum Ende des nächsten*/
ignoriert wird. Glücklicherweise macht das Hervorheben von Syntax solche Dinge heutzutage selten.a
Noch schlimmer für user_age? "Ja wirklich?"i = i + 1; //increment i
Code, der beim Kompilieren Warnungen ausgibt.
quelle
(unsigned int)
überladen, als meine Warn- / Fehlerlisten mit harmlosen Warnungen zu überladen. Ich würde es hassen, wenn die Warnliste ein blinder Fleck würde. Es ist auch viel mehr ein PITA zu anderen Menschen zu erklären , warum Sie eine Warnung zu ignorieren sind , als es zu erklären ist , warum Sie eine Besetzung von natürlichen tunints
zuunsigned ints
.Funktioniert mit Zahlen im Namen, anstatt beschreibende Namen zu haben , wie:
Bitte lassen Sie die Funktionsnamen etwas bedeuten! Wenn doSomething und doSomething2 ähnliche Aktionen ausführen, verwenden Sie Funktionsnamen, die die Unterschiede unterscheiden. Wenn doSomething2 ein Ausbruch aus der Funktionalität von doSomething ist, nennen Sie es für seine Funktionalität.
quelle
mshtml
- es bricht mir die Augen :(Magic Numbers oder Magic Strings.
quelle
200
, auf der anderen Seite ...Vielleicht nicht das schlechteste, zeigt aber deutlich die Implementierungsstufe:
Wenn eine Sprache eine for-Schleife oder ein Iteratorkonstrukt hat, zeigt die Verwendung einer while-Schleife auch, wie gut die Implementierer die Sprache verstehen:
Schlechte Rechtschreibung / Grammatik in Dokumentation / Kommentaren frisst bei mir fast so viel wie Code selbst. Der Grund dafür ist, dass Code für Menschen zum Lesen und für Maschinen zum Ausführen gedacht war. Aus diesem Grund verwenden wir Hochsprachen, wenn es schwierig ist, Ihre Dokumentation zu verarbeiten, kann ich mir eine negative Meinung über die Codebasis bilden, ohne sie anzusehen.
quelle
Das, was mir sofort auffällt, ist die Häufigkeit tief verschachtelter Codeblöcke (if's, while's usw.). Wenn Code häufig mehr als zwei oder drei Ebenen tief ist, deutet dies auf ein Design- / Logikproblem hin. Und wenn es 8 Nester tief geht, gibt es einen verdammt guten Grund, warum es nicht zerbrochen werden sollte.
quelle
return
Aussage haben sollte, aber wenn es 6+ Ebenen von Wenn / Dann-Verschachtelung verursacht, denke ich, dass es weit mehr schadet als nützt.Wenn ich ein Studentenprogramm benote, kann ich das manchmal in einem "Blink" -Moment feststellen. Dies sind die unmittelbaren Hinweise:
Selten sind meine ersten Eindrücke falsch, und diese Warnglocken stimmen in etwa 95% der Fälle . Für eine Ausnahme verwendete ein Student, der neu in der Sprache war, einen Stil aus einer anderen Programmiersprache. Das Nachlesen ihres Stils in der anderen Sprache löste die Alarmglocken für mich und der Student erhielt dann die volle Anerkennung. Aber solche Ausnahmen sind selten.
Wenn ich fortgeschritteneren Code betrachte, sind dies meine anderen Warnungen:
In Bezug auf den Stil sehe ich im Allgemeinen nicht gerne:
Dies sind nur Hinweise auf fehlerhaften Code. Manchmal ist das, was nach schlechtem Code aussieht, wirklich nicht der Fall, weil Sie die Absichten des Programmierers nicht kennen. Zum Beispiel mag es einen guten Grund dafür geben, dass etwas übermäßig komplex erscheint - es mag eine andere Überlegung gegeben haben.
quelle
Persönlicher Liebling / Haustier-Ärger: IDE-generierte Namen, die festgeschrieben werden. Wenn TextBox1 eine wichtige und wichtige Variable in Ihrem System ist, steht eine weitere Überprüfung des Codes an.
quelle
Völlig unbenutzte Variablen , insbesondere wenn die Variable einen ähnlichen Namen wie die verwendeten Variablennamen hat.
quelle
Viele Leute haben erwähnt:
Ich wünschte, das Zeug wäre implementiert, aber sie machten sich wenigstens eine Notiz. Was ich für schlimmer halte, ist:
Todos sind wertlos und verwirrend, wenn Sie sich nie die Mühe machen, sie zu entfernen!
quelle
//TODO
Kommentar? Genial!// TODO
, verwenden Sie Ihren Bug-Tracker, dafür ist er da!Eine Methode, bei der ich nach unten scrollen muss, um alles zu lesen.
quelle
Verknüpfungen in Methodennamen:
Klarstellung: Der Grund, warum diese Alarmglocken läuten, ist, dass sie anzeigt, dass die Methode wahrscheinlich gegen das Prinzip der einmaligen Verantwortung verstößt .
quelle
addEmployee(); updatePayrate();
) enthält, ist das meines Erachtens kein Problem.Offensichtlich GPL-Quellcode in ein kommerzielles Closed-Source-Programm einbinden.
Dies stellt nicht nur ein unmittelbares rechtliches Problem dar, sondern weist meiner Erfahrung nach in der Regel auch auf Unachtsamkeit oder Unbesorgtheit hin, die sich auch an anderen Stellen im Code widerspiegeln.
quelle
Sprachunabhängig:
TODO: not implemented
int function(...) { return -1; }
(das gleiche wie "nicht implementiert")0
,-1
odernull
als Ausnahmerückgabewert.Sprachspezifisch (C ++):
array new
, was anscheinend nicht RAII-sicher ist.printf
.Microsoft C ++ spezifisch:
C ++ / OOP-spezifisch:
quelle
Bizarrer Einrückungsstil.
Es gibt einige sehr beliebte Stile, und die Leute werden diese Debatte mit ins Grab nehmen. Aber manchmal sehe ich jemanden, der einen wirklich seltenen oder sogar einen einheimischen Einrückungsstil verwendet. Dies ist ein Zeichen dafür, dass sie wahrscheinlich mit niemand anderem als sich selbst codiert haben.
quelle
Verwenden Sie viele Textblöcke anstelle von Aufzählungen oder global definierten Variablen.
Nicht gut:
Besser:
Beste:
quelle
Schwach eingegebene Parameter oder Rückgabewerte für Methoden.
quelle
if...else
Block aussehen, sondern zu einemif...else if...[...]...else
Block werden$lesseeloginaccountservice
if
Aussagen. Beispiel aus dem Code: aufif (!($lessee_obj instanceof Lessee && $lessee_obj != NULL))
den ich heruntergebastelt habeif ($lessee_obj == null)
quelle
Code-Geruch: Best Practices nicht befolgen
Hier ist ein Blitz für Sie: 50% der Weltbevölkerung sind unterdurchschnittlich intelligent. Okay, einige Leute hätten genau die durchschnittliche Intelligenz, aber lassen Sie uns nicht wählerisch werden. Eine der Nebenwirkungen von Dummheit ist, dass Sie Ihre eigene Dummheit nicht erkennen können! Wenn Sie diese Aussagen kombinieren, sieht es nicht so gut aus.
Es wurden viele gute Dinge erwähnt, und im Allgemeinen scheint es ein Codegeruch zu sein, wenn Best Practices nicht befolgt werden.
Best Practices werden in der Regel nicht zufällig erfunden und sind häufig aus einem bestimmten Grund vorhanden. Oft kann es subjektiv sein, aber meiner Erfahrung nach sind sie meist gerechtfertigt. Das Befolgen von Best Practices sollte kein Problem sein, und wenn Sie sich fragen, warum sie so sind, recherchieren Sie sie, anstatt sie zu ignorieren und / oder sich darüber zu beschweren - vielleicht ist es gerechtfertigt, vielleicht nicht.
Ein Beispiel für eine bewährte Methode ist die Verwendung von Curlies für jeden if-Block, auch wenn dieser nur eine Zeile enthält:
Sie denken vielleicht nicht, dass es notwendig ist, aber ich habe kürzlich gelesen, dass es eine Hauptquelle für Fehler ist. Die Verwendung von eckigen Klammern wurde auch im Zusammenhang mit dem Stapelüberlauf erörtert. Die Überprüfung, ob if-Anweisungen eckige Klammern enthalten, ist auch in PMD , einem statischen Codeanalysator für Java, eine Regel .
Denken Sie daran: "Weil es sich um bewährte Methoden handelt" ist keine akzeptable Antwort auf die Frage "Warum machen Sie das?" Wenn Sie nicht artikulieren können, warum etwas ein bewährtes Verfahren ist, dann ist es kein bewährtes Verfahren, sondern ein Aberglaube.
quelle
Kommentare, die besagen: "Das liegt daran, dass das Design des Froz-Subsystems völlig durcheinander ist."
Das geht über einen ganzen Absatz.
Sie erklären, dass der folgende Refactor passieren muss.
Aber habe es nicht getan.
Jetzt wurde ihnen vielleicht gesagt, dass sie es von ihrem Chef zu der Zeit aus Zeit- oder Kompetenzgründen nicht ändern konnten, aber vielleicht lag es daran, dass die Leute kleinlich waren.
Wenn ein Vorgesetzter das für zufällig hält. Der Programmierer kann kein Refactoring durchführen, dann sollte der Supervisor dies tun.
Wie dem auch sei, ich weiß, dass der Code von einem geteilten Team mit möglicher Machtpolitik geschrieben wurde, und sie haben die Entwürfe von gegabelten Subsystemen nicht überarbeitet.
Wahre Geschichte. Das könnte dir geschehen.
quelle
Kann jemand an ein Beispiel denken, in dem Code legitimerweise auf eine Datei durch absoluten Pfad verweisen sollte?
quelle
/dev/null
und freunden geht es gut Aber selbst/bin/bash
solche Dinge sind verdächtig - was ist, wenn Sie ein verrücktes System sind, das es gibt/usr/bin/bash
?/home/tom/dev/randomhacking/thing.wsdl
. Es ist kriminell verrückt, dass dies ein Standardverhalten ist./dev/null
: Ich habe die Gewohnheit, bei der Entwicklung auf Windows Apps und Bibliotheken unterzuhaltenc:\dev
. Irgendwienull
wird immer automatisch ein Ordner in diesem Ordner erstellt. Ich schwöre, ich habe keine Ahnung, wer das tut. (Einer meiner Lieblingsfehler / Features)Allgemeine Ausnahmen:
oder
Überbeanspruchung der Region
In der Regel bedeutet die Verwendung zu vieler Regionen, dass Ihre Klassen zu groß sind. Es ist eine Warnflagge, die signalisiert, dass ich mich eingehender mit diesem Code befassen sollte.
quelle
Klassennamenskonventionen, die ein schlechtes Verständnis der Abstraktion zeigen, die sie erstellen möchten. Oder das definiert überhaupt keine Abstraktion.
Ein extremes Beispiel
Data
fällt mir in einer VB-Klasse ein, die ich einmal gesehen habe und die über 30.000 Zeilen lang war ... in der ersten Datei. Es war eine Teilklasse, die in mindestens ein halbes Dutzend andere Dateien aufgeteilt war. Die meisten Methoden waren Wrapper um gespeicherte Procs mit Namen wieFindXByYWithZ()
.Selbst mit weniger dramatischen Beispielen bin ich sicher, dass wir alle die Logik in eine schlecht konzipierte Klasse "geworfen" haben, indem wir ihr einen ganz allgemeinen Titel gegeben haben und es später bereut haben.
quelle
Funktionen, die grundlegende Funktionen der Sprache neu implementieren. Wenn Sie beispielsweise jemals eine "getStringLength ()" - Methode in JavaScript anstelle eines Aufrufs der ".length" -Eigenschaft eines Strings sehen, wissen Sie, dass Sie in Schwierigkeiten sind.
quelle
Natürlich ohne jegliche Dokumentation und die gelegentlich verschachtelten
#define
squelle