4 Punkte von GN⁺ 2024-10-30 | 1 Kommentare | Auf WhatsApp teilen

Code schreiben, der sich leicht löschen lässt

  • Jede Codezeile verursacht Wartungskosten. Code-Wiederverwendung erschwert Änderungen.
  • Je mehr API-Konsumenten es gibt, desto mehr Code muss bei Änderungen umgeschrieben werden.
  • Die Abhängigkeiten von Code zu verwalten, ist in großen Systemen ein wichtiges Problem.

Stufe 0: Keinen Code schreiben

  • Die Anzahl der Codezeilen liefert für sich genommen nicht viele Informationen.
  • Nicht geschriebener Code ist der Code, der sich am leichtesten löschen lässt.

Stufe 1: Code kopieren und einfügen

  • Wiederverwendbarer Code lässt sich später anhand von Beispielen leichter schreiben.
  • Code zu kopieren und einzufügen ist eine Methode, Abhängigkeiten zu vermeiden und Flexibilität zu gewinnen.

Stufe 2: Code nicht kopieren und einfügen

  • Wenn Code oft genug kopiert und eingefügt wurde, ist es Zeit, ihn in eine Funktion auszulagern.
  • Es ist gut, ein util-Verzeichnis anzulegen und verschiedene Utilities in anderen Dateien aufzubewahren.

Stufe 3: Mehr Boilerplate schreiben

  • Boilerplate ähnelt dem Kopieren und Einfügen von Code, nur dass der Code an jeweils unterschiedlichen Stellen geändert wird.
  • Boilerplate reduziert Abhängigkeiten und bietet Flexibilität.

Stufe 4: Keine Boilerplate schreiben

  • Wenn es zu viel Boilerplate gibt, sollte man sie mit einer Library umhüllen, die eine klare Meinung zu Richtlinien, Workflows und Zustand hat.
  • Die Beziehung zwischen requests und urllib3 ist ein gutes Beispiel dafür.

Stufe 5: Große Codeblöcke schreiben

  • Geschäftslogik ist durch endlose Ausnahmefälle und schnelle, schmutzige Hacks gekennzeichnet.
  • Einen großen Fehler zu löschen ist einfacher, als viele kleine Fehler zu löschen.

Stufe 6: Code in Teile zerlegen

  • Große Codeblöcke verursachen hohe Wartungskosten.
  • Man sollte Verantwortlichkeiten im Code trennen und Module mit Blick auf mögliche Änderungen entwerfen.

Stufe 7: Weiterhin Code schreiben

  • Es sollte möglich sein, unabhängig vom bestehenden Code neuen Code zu schreiben, damit sich neue Ideen ausprobieren lassen.
  • Feature Flags sind eine Möglichkeit, später die Meinung zu ändern.

Zusammenfassung von GN⁺

  • Dieser Artikel erklärt, wie man Code schreibt, der sich beim Entwickeln leicht wieder löschen lässt.
  • Entscheidend ist, Abhängigkeiten im Code zu verringern, die Flexibilität zu erhöhen und die Wartungskosten zu senken.
  • Ähnliche Projekte mit vergleichbarer Funktionalität sind requests und urllib3.
  • Der Artikel erinnert Softwareentwickler an die Bedeutung von Code-Management und Wartbarkeit.

1 Kommentare

 
GN⁺ 2024-10-30
Hacker-News-Kommentare
  • Mir gefällt der Satz „Simple is robust“. Er bedeutet, dass ein System umso leichter zu ändern ist, je geringer seine Komplexität ist. Für die Zukunft sollte man eher mit intuitivem Code planen als mit skalierbarem Code. Zum Beispiel nur dann abstrahieren, wenn die Situation es verlangt, einfache Duplizierung fördern, anfangs einen Monolithen verwenden und vertikale Skalierung vor horizontaler bevorzugen. Beim Aufbau mehrerer 0-1-Systeme habe ich diese Gemeinsamkeiten festgestellt.

  • Es überrascht mich, dass Tests oder Observability nicht erwähnt werden. Tests verursachen zwar Wartungskosten, senken aber das Risiko von Problemen beim Entfernen von Code. Wenn man einen Service externen Aufrufern bereitstellt, braucht man eine starke Methode, um einige Aufrufe als veraltet zu markieren und zu beobachten, ob sie weiterhin verwendet werden. Ich habe vor Kurzem GraphQL-Resolver halbautomatisch entfernt und anhand von Nutzungsmetriken festgestellt, welche Resolver noch nicht gelöscht werden konnten. GraphQL hat zwar Deprecation-Anmerkungen, aber im Service wurden sie nicht besonders behandelt. Durch zusätzliche Observability kann man ein Flag setzen, wenn eine veraltete Funktion aufgerufen wurde, und nach ausreichend langer Laufzeit in Produktion extern exponierten Code sicher löschen.

  • Ich ertappe mich dabei, für „Design zum Löschen“ zu werben. Früher dachte ich, ich könnte etwas schaffen, das für alle Situationen geplant ist und jeden Bedarf erfüllt, aber zukünftige Anforderungen vorherzusagen ist schwierig. Irgendwann wird etwas, das ich gebaut habe, für jemanden nutzlos sein, und dann wird es gerechtfertigt sein, es abzureißen. Deshalb sollte man sich Mühe geben, Dinge leicht entfernbar zu machen. Das führt oft zu geringerer Kopplung, ist aber etwas anderes als die Haltung junger Entwickler, alles in meta-konfigurierbare Frameworks aufzuspalten. Manchmal ist enge Kopplung besser, wenn sie logisch leichter zu verstehen ist.

  • Um Code so zu schreiben, dass er leicht gelöscht werden kann, sollte man Wiederholung in Kauf nehmen, um Abhängigkeiten zu vermeiden, aber nicht wiederholen, um etwas zu verwalten. Man sollte Code-Schichten trennen und einfache APIs über Bereichen aufbauen, die zwar simpel zu implementieren, aber unbequem zu benutzen sind. Man sollte den Code separieren und die schwer zu schreibenden Teile sowie die Teile mit hoher Änderungswahrscheinlichkeit vom Rest des Codes und voneinander trennen. Nicht jede Entscheidung sollte hartkodiert sein; einige Dinge sollten sich zur Laufzeit ändern lassen. Meiner persönlichen Erfahrung nach ist Code, der leicht zu löschen ist, geschichtet und modularisiert und dadurch auch leicht zu erweitern.

  • Ich sage Studierenden der Computational Physics seit jeher, dass die beste Berechnung die ist, um die man sich nicht kümmern muss.

  • Ich persönlich teile Code in Business-Logik und tatsächliche Implementierung auf. Business-Logik darf ihrer Natur nach dupliziert sein, aber zu viele technische Details sollten nicht dupliziert werden. Solange man die Business-Logik nicht direkt behandelt und sie anwendungsunabhängig hält, darf sie so chaotisch sein, wie man will. Wenn Probleme auftreten und etwas nicht gut funktioniert, hat man die Möglichkeit, die gesamte Implementierung zu löschen, sie zu korrigieren und wird nicht dazu gezwungen, die eigentliche Spezifikation in der Implementierung zu suchen.

  • Ein offensichtlicher Fehler im ersten Absatz: Das Problem bei Wiederverwendung von Code sei, dass sie einen später daran hindere, seine Meinung zu ändern. Das ist im Allgemeinen eine falsche Behauptung. Wenn man seine Meinung ändert und der Code an zehn Stellen kopiert und eingefügt wurde, muss man zehn Stellen ändern. Wenn der Code dagegen in einer Funktion steckt, muss man ihn nur einmal ändern. Falls einer von zehn Aufrufen doch anders bleiben soll, kann man immer noch kopieren und einfügen oder die Funktion allgemeiner machen. So wie man beim Überqueren der Straße nach beiden Seiten schaut, ist Copy-and-paste fast immer eine schlechte Idee.

  • Es gibt eine hervorragende Korrelation dafür, dass schlechter Code lange bestehen bleibt, weil er schwer zu entfernen ist.

  • Ich frage mich, ob damit gemeint ist, Software so weit wie möglich im Standardzustand zu verwenden und nicht tiefgreifend anzupassen.