10 schlechte Programmiergewohnheiten, die wir heimlich lieben

Wir haben es alle geschafft: einen Keks geschnappt, als Mama nicht hinschaute, etwas zu viel Wein zum Abendessen hatte, das Auto nach Ablauf des Zählers auf einem Parkplatz stehen lassen. Wir haben Deadman's Curve sogar etwas zu schnell umgangen. Und ja, wir haben alle gegen eine Reihe von Grundregeln der Programmierung verstoßen, die, denen alle zustimmen, sind schlecht. Und es hat uns insgeheim gefallen.

Wir haben uns die Regeln für eine gute Programmierung angesehen, Code eingegeben, der völlig schlecht ist - und wir haben gelebt. Es gab keine Blitze von den Programmiergöttern. Unsere Desktops sind nicht explodiert. Tatsächlich wurde unser Code kompiliert und versendet, und die Kunden schienen glücklich genug zu sein.

Das liegt daran, dass schlechte Programmierung nicht in der gleichen Liga liegt wie beispielsweise das Lecken eines Elektrozauns oder das Ziehen des Schwanzes eines Tigers. Meistens klappt es. Die Regeln sind häufiger Richtlinien oder Stilvorschläge, keine festen Anweisungen, die befolgt werden müssen, sonst folgt der Tod des Codes. Sicher, Ihr Code könnte lächerlich gemacht werden, möglicherweise sogar öffentlich. Aber die Tatsache, dass Sie sich gegen Konventionen sträuben, macht es ein wenig spannend, selbst versehentlich zu untergraben, was (meistens) den sozialen Sitten eines angenehmen Codes entspricht.

Um die Sache komplexer zu gestalten, ist es manchmal besser, die Regeln zu brechen. (Shhhh!) Der Code kommt sauberer heraus. Es kann sogar schneller und einfacher sein. Die Regeln sind normalerweise etwas zu weit gefasst, und ein geschickter Programmierer kann den Code verbessern, indem er sie bricht. Sagen Sie es Ihrem Chef nicht, aber manchmal ist es sinnvoll, Ihren eigenen Weg zu codieren.

Was folgt, ist eine Liste von neun Regeln, die einige für unanfechtbar halten, aber viele von uns brechen oft mit Erfolg und Vergnügen.

Schlechte Programmiergewohnheit Nr. 1: Kopieren 

Es ist falsch, es in der Schule zu machen. Bei der Arbeit sind die Regeln nicht so klar. Es gibt sicherlich einige Codeblöcke, die nicht gestohlen werden sollten. Wenn es aus proprietärem Code stammt, falten Sie es nicht in Ihren Stapel, insbesondere wenn es mit einer Copyright-Meldung gekennzeichnet ist. Schreiben Sie Ihre eigene Version. Dafür bezahlen sie dich.

Die schwierigere Frage kommt, wenn der ursprüngliche Schöpfer teilen möchte. Vielleicht ist es in einem dieser Online-Programmierforen. Vielleicht ist es Open Source Code mit einer Lizenz (BSD, MIT), die es erlaubt, ein oder drei Funktionen zu knacken. Es gibt keinen rechtlichen Grund, Sie aufzuhalten. Und Sie werden dafür bezahlt, Probleme zu lösen und das Rad nicht neu zu erfinden.

Meistens sind die Vorteile des Kopierens überzeugend und die Nachteile können mit ein wenig Sorgfalt begrenzt werden. Auf den Code, den Sie von einer seriösen Quelle erhalten, wurde bereits mindestens eine Gedankenrunde angewendet. Der ursprüngliche Autor suchte nach einer Lösung und fand etwas. Die Schleifeninvarianten und der Datenfluss wurden ausgearbeitet.

Die kniffligen Fragen sind, ob es einige nicht gefundene Fehler oder andere Annahmen über die Rolle oder die zugrunde liegenden Daten gibt. Möglicherweise mischt Ihr Code Nullzeiger ein, während der ursprüngliche Code sie nie überprüft hat. Wenn Sie die Probleme beheben können, ist es so, als würde Ihr Chef die Eingabe von zwei Programmierern erhalten. Es ist Paarprogrammierung ohne die ausgefallenen Schreibtische.

Schlechte Programmiergewohnheit Nr. 2: Nicht funktionierender Code

In den letzten zehn Jahren ist das funktionale Paradigma aufgestiegen. Die Akolythen zum Erstellen Ihres Programms aus verschachtelten Funktionsaufrufen zitieren gerne Studien, die zeigen, wie der Code sicherer und fehlerfreier ist als der ältere Stil von Variablen und Schleifen, die alle auf irgendeine Weise aneinandergereiht sind, was den Programmierer glücklich macht. Die Devotees sprechen mit dem Eifer wahrer Gläubiger und züchtigen nicht funktionierende Ansätze bei Codeüberprüfungen und Pull-Anfragen. Sie können sogar in Bezug auf die Vorteile Recht haben.

Aber manchmal muss man nur eine Rolle Klebeband herausholen. Wunderbar konstruierter und elegant geplanter Code braucht Zeit, um sich nicht nur vorzustellen, sondern auch zu konstruieren und später zu navigieren. Alle diese Schichten erhöhen die Komplexität, und Komplexität ist teuer. Entwickler von schönem Funktionscode müssen vorausplanen und sicherstellen, dass alle Daten auf den richtigen Wegen übertragen werden. Manchmal ist es einfacher, eine Variable zu erreichen und zu ändern. Vielleicht einen Kommentar einfügen, um es zu erklären. Selbst das Hinzufügen einer langen, grovelnden Entschuldigung für zukünftige Generationen in dem Kommentar ist schneller als das Umgestalten des gesamten Systems, um es richtig zu machen.

Schlechte Programmiergewohnheit Nr. 3: Nicht standardmäßiger Abstand

Die meisten Bereiche in der Software haben keinen Einfluss auf die Leistung des Programms. Mit Ausnahme einiger Sprachen wie Python, die den Abstand zur Angabe von Codeblöcken verwenden, haben die meisten Leerzeichen keinen Einfluss auf das Verhalten des Programms. Dennoch gibt es obsessive Programmierer, die sie zählen und darauf bestehen, dass sie wichtig sind. Einer von ihnen sagte meinem Chef einmal im ernstesten Ton, dass ich „Non Standard Code“ schreibe und er es sofort sehen könne. Meine Sünde? Verstoß gegen die ESLint-Space-Infix-Ops-Regel, indem auf beiden Seiten eines Gleichheitszeichens kein Leerzeichen eingefügt wird.

Manchmal muss man nur über etwas tieferes nachdenken als über die Platzierung von Räumen. Vielleicht machen Sie sich Sorgen, dass die Datenbank überlastet wird. Vielleicht machen Sie sich Sorgen darüber, dass ein Nullzeiger Ihren Code zum Absturz bringen könnte. Nahezu jeder Teil des Codes ist wichtiger als die Leerzeichen, auch wenn die nebeligen, herrschenden Normungsausschüsse Seiten mit Regeln für die Platzierung dieser Leerzeichen oder Registerkarten ausgefüllt haben.

Das Erstaunliche ist, dass es mehrere gute Tools gibt, die Ihren Code automatisch neu formatieren, um genau definierte Flusenregeln einzuhalten. Menschen müssen keine Zeit damit verbringen, darüber nachzudenken. Wenn es so wichtig ist, können sie es durch das Tool ausführen, um das Problem zu beheben.

Schlechte Programmiergewohnheit Nr. 4: Verwenden goto

Das Verbot, gotoDaten aus der Zeit zu verwenden, bevor viele Werkzeuge der strukturierten Programmierung überhaupt existierten. Wenn Programmierer eine Schleife erstellen oder zu einer anderen Routine springen möchten, müssen sie GOTOgefolgt von einer Zeilennummer eingeben. Nach einigen Jahren ließen Compilerteams Programmierer eine Zeichenfolgenbezeichnung anstelle einer Zeilennummer verwenden. Das galt damals als heißes neues Feature.

Einige nannten das Ergebnis "Spaghetti-Code". Es war für niemanden möglich, Ihren Code später zu lesen und dem Ausführungspfad zu folgen. Es war ein Durcheinander von Fäden, die für immer verwickelt waren. Edsger Dijkstra verbot den Befehl mit einem Manuskript mit dem Titel "Gehe zu Aussage, die als schädlich angesehen wird".

Aber absolute Verzweigung ist nicht das Problem. Es ist das Gewirr, das daraus resultiert. Oft eine kunstvolle breakoder returnbietet eine sehr saubere Aussage darüber, was der Code an diesem Ort tut. Manchmal führt das Hinzufügen gotozu einer case-Anweisung zu etwas, das einfacher zu verstehen ist als eine besser strukturierte Liste von kaskadierenden If-Then-else-Blöcken.

Es gibt Gegenbeispiele. Die Sicherheitslücke "goto fail" im SSL-Stack von Apple ist eine der besten Instanzen. Wenn wir jedoch darauf achten, einige der knorrigen Probleme von case-Anweisungen und Schleifen zu vermeiden, können wir gute, absolute Sprünge einfügen, die es dem Leser erleichtern, zu verstehen, was vor sich geht. Wir können ein breakoder ein setzen return, das sauberer und angenehmer für alle ist - außer vielleicht für die gotoHasser.

Schlechte Programmiergewohnheit Nr. 5: Keine Typen deklarieren

Die Leute, die getippte Sprachen lieben, haben einen Punkt. Wir schreiben besseren, fehlerfreieren Code, wenn wir eindeutige Deklarationen des Datentyps jeder Variablen hinzufügen. Wenn Sie einen Moment innehalten, um den Typ zu formulieren, kann der Compiler dumme Fehler melden, bevor der Code ausgeführt wird. Es mag ein Schmerz sein, aber es hilft. Es ist ein Gürtel-und-Hosenträger-Ansatz für die Programmierung, der Fehler stoppt.

Die Zeiten haben sich geändert. Viele der neueren Compiler sind klug genug, um den Typ anhand des Codes abzuleiten. Sie können den Code vorwärts und rückwärts durcharbeiten, bis sie sicher sein können, dass die Variable eine stringoder eine intoder etwas anderes sein muss. Und wenn diese abgeleiteten Typen nicht übereinstimmen, können die Compiler ein Fehlerflag auslösen. Wir müssen die Variablen nicht mehr eingeben.

Dies bedeutet, dass es jetzt einfacher ist, einige Bits zu speichern, indem einige der einfachsten Deklarationen weggelassen werden. Der Code wird etwas sauberer, und der Leser kann normalerweise gut erraten, dass die iin einer for-Schleife genannte Variable eine Ganzzahl ist.

Schlechte Programmiergewohnheit Nr. 6: Jojo-Code

Programmierer nennen es gerne "Jo-Jo-Code". Zuerst werden die Werte als Zeichenfolgen gespeichert. Dann werden sie in ganze Zahlen analysiert. Dann werden sie wieder in Strings umgewandelt. Es ist schrecklich ineffizient. Sie können fast spüren, wie die CPU unter all der zusätzlichen Last kämpft. Intelligente Programmierer, die schnellen Code schreiben, entwerfen ihre Architekturen, um die Konvertierungen zu minimieren. Ihr Code läuft aufgrund ihrer Planung schneller.

Aber ob Sie es glauben oder nicht, manchmal macht es Sinn. Manchmal haben Sie eine Whiz-Bang-Bibliothek, die eine Unmenge intelligenter Dinge in ihrer proprietären Black Box erledigt. Manchmal schrieb der Chef einen siebenstelligen Scheck, um das ganze Genie in dieser Black Box zu lizenzieren. Wenn die Bibliothek die Daten in Zeichenfolgen haben möchte, geben Sie sie in Zeichenfolgen an die Bibliothek weiter, auch wenn Sie sie kürzlich in Ganzzahlen konvertiert haben.

Sicher, Sie könnten Ihren gesamten Code neu schreiben, um die Konvertierung zu minimieren, aber das würde einige Zeit dauern. Manchmal ist es in Ordnung, dass der Code eine zusätzliche Minute, Stunde, Tag oder sogar Woche ausführt, da das Umschreiben des Codes noch mehr Zeit in Anspruch nimmt. Manchmal ist es billiger, die technischen Schulden zu erhöhen, als sie direkt aufzubauen.

Manchmal ist die Bibliothek kein proprietärer Code, sondern Code, den Sie selbst vor langer Zeit geschrieben haben. Manchmal ist es schneller, die Daten noch einmal zu konvertieren, als alles in dieser Bibliothek neu zu schreiben. Also machst du mit und schreibst Jojo-Code. Es ist in Ordnung - wir waren alle dort.

Schlechte Programmiergewohnheit Nr. 7: Schreiben eigener Datenstrukturen

Eine der Standardregeln ist, dass ein Programmierer niemals Code zum Speichern von Daten schreiben sollte, nachdem er den Datenstrukturkurs in seinem zweiten Jahr abgeschlossen hat. Jemand anderes hat bereits alle Datenstrukturen geschrieben, die wir jemals benötigen werden, und ihr Code wurde im Laufe der Jahre getestet und erneut getestet. Es ist mit der Sprache gebündelt und wahrscheinlich kostenlos. Ihr Code konnte nur Fehler enthalten.

Aber manchmal sind die Datenstrukturbibliotheken etwas langsam. Manchmal zwingen sie uns in eine Struktur, die vielleicht Standard ist, aber für unseren Code falsch. Manchmal zwingen uns die Bibliotheken dazu, unsere Daten neu zu konfigurieren, bevor wir die Struktur verwenden. Manchmal enthalten die Bibliotheken Schutzvorrichtungen für Riemen und Hosenträger mit Funktionen wie Thread-Sperre, und unser Code benötigt sie nicht.

In diesem Fall ist es Zeit, eigene Datenstrukturen zu schreiben. Manchmal ist es viel, viel schneller. Und manchmal macht es unseren Code viel sauberer, weil wir nicht den gesamten zusätzlichen Code für die Neuformatierung der Daten genau so einschließen.

Schlechte Programmiergewohnheit Nr. 8: Altmodische Loops

Vor langer Zeit wollte jemand, der die C-Sprache erstellt, alle abstrakten Möglichkeiten in einem einfachen Konstrukt zusammenfassen. Zu Beginn waren einige Dinge zu tun, einige Dinge, die jedes Mal durch die Schleife zu tun waren, und eine Möglichkeit, festzustellen, wann alles erledigt war. Zu dieser Zeit schien es eine vollkommen saubere Syntax zu sein, um unendliche Möglichkeiten zu erfassen.

Das war damals. Jetzt sehen einige moderne Schelte nur noch Ärger. Es sind zu viele Dinge los. Alle diese Möglichkeiten des Guten sind auch zum Bösen fähig. Es macht das Lesen und Grokken so viel schwieriger. Sie lieben das funktionalere Paradigma, bei dem es keine Schleifen gibt, sondern nur Funktionen, die auf Listen angewendet werden, Rechenvorlagen, die einigen Daten zugeordnet sind.

Es gibt Zeiten, in denen der schleifenlose Weg sauberer ist, insbesondere wenn es nur eine nette Funktion und ein Array gibt. Aber es gibt Zeiten, in denen die altmodische Schleife viel einfacher ist, weil sie viel mehr kann. Die Suche nach dem ersten Spiel ist beispielsweise einfacher, wenn Sie aufhören können, sobald es gefunden wurde.

Darüber hinaus fördern Mapping-Funktionen eine schlampigere Codierung, wenn mehrere Dinge an den Daten zu tun sind. Stellen Sie sich vor, Sie möchten den absoluten Wert und dann die Quadratwurzel jeder Zahl nehmen. Die schnellste Lösung besteht darin, die erste und dann die zweite Funktion abzubilden und die Daten zweimal zu durchlaufen. 

Schlechte Programmiergewohnheit Nr. 9: Ausbrechen von Schleifen in der Mitte

Irgendwann erklärte eine Regelgruppe, dass jede Schleife eine „Invariante“ haben sollte, dh eine logische Aussage, die in der gesamten Schleife wahr ist. Wenn die Invariante nicht mehr wahr ist, endet die Schleife. Es ist eine gute Möglichkeit, über komplexe Schleifen nachzudenken, aber es führt zu verrückten Verboten - wie dem Verbot, ein returnoder ein breakin der Mitte der Schleife zu verwenden. Dies ist eine Teilmenge der Regel, die gotoAussagen verbietet .

Diese Theorie ist in Ordnung, führt aber normalerweise zu komplexerem Code. Stellen Sie sich diesen einfachen Fall vor, in dem ein Array nach einem Eintrag durchsucht wird, der einen Test besteht:

während ich
   
    

   ...

   if (test (a [i]) dann gebe a [i] zurück;

   ...

}}

Die Liebhaber der Schleifeninvarianten möchten lieber eine weitere boolesche Variable hinzufügen, sie aufrufen notFoundund wie folgt verwenden:

while ((notFound) && (i
   
    

...

if (test (a [i])) dann notFound = false;

...

}}

Wenn dieser Boolesche Wert gut benannt ist, ist er ein großartiger selbstdokumentierender Code. Es kann für jeden leichter verständlich sein. Aber es ist auch zusätzliche Komplexität. Und es bedeutet, eine andere lokale Variable zuzuweisen und ein Register zu verstopfen, das der Compiler möglicherweise intelligent genug ist, um es zu reparieren.

Manchmal ist ein gotooder ein Sprung sauberer.

Schlechte Programmiergewohnheit Nr. 10: Operatoren und Funktionen neu definieren

Mit einigen der unterhaltsamsten Sprachen können Sie wirklich falsche Dinge tun, z. B. den Wert von Elementen neu definieren, die so aussehen, als ob sie konstant sein sollten. Mit Python können Sie beispielsweise TRUE=FALSEzumindest in Version 2.7 und früher eingeben. Dies führt nicht zu einem logischen Zusammenbruch und dem Ende des Universums. es tauscht einfach die Bedeutung von TRUEund aus FALSE. Sie können auch gefährliche Spiele wie dieses mit C-Präprozessoren und einigen anderen Sprachen spielen. In weiteren Sprachen können Sie Operatoren wie das Pluszeichen neu definieren.

Dies ist eine Strecke, aber es wird Punkte innerhalb eines großen Codeblocks geben, wenn es schneller ist, eine oder mehrere dieser sogenannten Konstanten neu zu definieren. Manchmal möchte der Chef, dass der Code etwas ganz anderes macht. Sicher, Sie könnten den Code durcharbeiten und jedes Vorkommen ändern oder die Realität neu definieren. Es kann dich wie ein Genie aussehen lassen. Anstatt eine riesige Bibliothek neu zu schreiben, drehen Sie einfach ein bisschen um und es macht das Gegenteil.

Vielleicht ist es gut, hier die Grenze zu ziehen. Sie sollten dies nicht zu Hause versuchen, egal wie clever und unterhaltsam es sein kann. Das ist zu gefährlich - wirklich ... ehrlich.