CODE-REVIEW · ENGINEERING · METHODIK

Wir haben die Meister der Softwareentwicklung an den Review-Tisch geholt

· 10 Min. Lesezeit

Wie ein Regal alter Bücher unsere Reviews schärfte und warum klar benannte Perspektiven eine gute Checkliste nützlicher machen.

Die Reviewrunde, seit 1975 - immer dabei, 1975 bis 2018 in einem Regal. Der Rest wird nur aufgerufen, wenn der Code danach verlangt.

In unserem Büro steht ein Regal. Darauf: Brooks über den mythischen Mannmonat, Ousterhout über die Philosophie des Softwaredesigns, Kleppmann über Systeme, die Daten speichern und bewegen, Anderson über Security Engineering, ein zerlesener Dijkstra, ein Feathers mit gebrochenem Buchrücken. Die meisten Autoren sind im Ruhestand. Manche sind tot. Und alle, wie sich zeigt, sind hervorragende Code-Reviewer.

Dieser Essay handelt von einer kleinen Idee, die ganz unauffällig verändert hat, wie wir Software prüfen. Sie lautet: Wenn eine Maschine Ihren Code mit Urteilskraft statt bloßer Höflichkeit kritisieren soll, dann fragen Sie nicht, ob der Code gut ist. Nennen Sie die Person, die es wüsste.

Das Problem

Der Haken an „sieht gut aus"

Legen Sie einem leistungsfähigen Modell eine Funktion vor und fragen Sie nach seiner Meinung, wird es meist zustimmen. Sieht solide aus. Vielleicht noch etwas Fehlerbehandlung. Erwägen Sie, eine Hilfsfunktion auszulagern. Nichts davon ist falsch. Nur hat diese Stimme kein eigenes Profil. Es ist das Review, das Sie von einer sehr belesenen Person bekämen, die vor Ihnen lieber keine Meinung hätte.

Ein Review ohne Standpunkt ist Autovervollständigung mit Kompliment. Wer Ihnen wirklich hilft, ist die Instanz mit einer klaren, teuer erarbeiteten Vorstellung davon, was gute Software ausmacht, und dem Mut, sich mit weniger nicht zufriedenzugeben. Diese Instanz ist selten eine Checkliste. Checklisten erkennen, was fehlt. Sie schweigen oft darüber, wenn das Falsche vorhanden ist, und genau dort wohnen die interessanten Fehler.

Die Idee

Nennen Sie den Meister

Also fingen wir an, Namen zu nennen. Statt „prüfe das auf Designprobleme" fragten wir: Was würde John Ousterhout zu dieser Schnittstelle sagen? Der Wechsel war nicht kosmetisch. Ein Name ist der kompakteste Verweis, den wir kennen, auf ein ganzes Reservoir an Urteilskraft.

John Ousterhout, A Philosophy of Software Design (2018). Tiefe Module bieten eine einfache Schnittstelle, hinter der echte Komplexität verborgen bleibt. Der Wert eines Moduls bemisst sich daran, wie viel es den Lesenden zu vergessen erlaubt.

Nennen Sie bei Code, der Daten speichert oder repliziert, den Namen Kleppmann, und Sie rufen keine Tatsache ab. Sie rufen eine dauerhafte Wachsamkeit auf: für Idempotenz, für das, was „genau einmal" wirklich verspricht, und für die Selbsttäuschung jedes verteilten Wiederholungsversuchs. Neun Buchstaben, eine ganze Laufbahn hart erarbeiteter Skepsis. Nennen Sie bei einem Parser den Namen Ross Anderson, und die Vertrauensgrenze leuchtet auf. Nennen Sie bei einer Kette von Vielleicht-Null-Rückgaben den Namen Hoare, und der Milliarden-Dollar-Fehler steht plötzlich im Raum.

Wir nennen ein solches Paar einen semantischen Anker: einen Meister samt dem Werk, für das er bekannt ist, genau dort platziert, wo der Code sein Fachgebiet berührt.

Die Arbeitsdefinition, nach der dieser Essay benannt ist.

Der Anker stößt den Abruf an. Sie beschreiben nicht, wonach zu suchen ist; Sie rufen die Person herbei, die ihr Leben damit verbracht hat, nach genau dem zu suchen.

Das System

Vom Kniff zur Jury

Ein Kniff, den man von Hand anwendet, ist ein Kniff, den man unter Termindruck vergisst. Also bauten wir die Jury in die Methode selbst ein. Eine kleine Stammbesetzung ist immer dabei: die Generalisten von Entwurf und Handwerk, die zu jeder Codeeinheit etwas zu sagen haben. Um sie herum sitzt eine Reserve, und das ist der Teil, den wir mögen. Welche Meister aus der Reserve dazukommen, bestimmt eine Eigenschaft des Codes - nie die Laune des Reviewers.

Der Code öffnet eine Datenbankverbindung, und Kleppmann und Jim Gray rücken die Stühle heran. Er bastelt ein Token von Hand, und Schneier und Anderson beugen sich vor. Er greift zu unsicherem Rust, und ein ganz bestimmtes Buch schlägt sich wie von selbst auf. Das Regal ist keine Dekoration. Es ist ein Index, und der Code ist die Abfrage. Das ist der ganze Kniff: Ihre Bibliothek, ausführbar gemacht.

Ein Name ist der kompakteste Verweis, den wir kennen, auf ein ganzes Reservoir an Urteilskraft. Der Anker stößt den Abruf an.

In der Praxis

Eine Funktion, drei Meister

Hier sind sechs Zeilen, die Sie in der einen oder anderen Form schon hundertmal geschrieben haben. Ein Cache vor einer Abfrage.

get-user.js
async function getUser(id) {
  const hit = cache.get(id)
  if (hit) return hit
  const user = await db.query(
    "SELECT * FROM users WHERE id = " + id
  )
  cache.set(id, user)
  return user
}

Im glücklichen Pfad funktioniert es, und ein Review, das nur auf die Ausführung schaut, könnte es durchwinken. Jetzt lassen wir die Jury herein.

Ross Anderson Security Engineering

Wo verläuft die Vertrauensgrenze, und was überquert sie ungeprüft?

Die id wird direkt in SQL zusammengesetzt. Wer 1 OR 1=1 übergibt, liest jeden Benutzer; eine bösere Zeichenkette tut Böseres. Die Grenze zwischen „Argument" und „Abfrage" wurde nie gezogen. Das ist keine Stilnotiz. Das ist die ganze Datenbank.

Mechanisch · sofort beheben
John Ousterhout A Philosophy of Software Design

Wie viel muss die aufrufende Seite im Kopf behalten, um das sicher zu benutzen?

Die Schnittstelle verspricht „gib mir einen Benutzer", verrät aber eine Caching-Strategie, die der Aufrufer weder sieht noch steuern noch invalidieren kann. Und SELECT * verschweißt den Cache mit der vollständigen Struktur der Datenbankzeile, sodass eine neue Spalte still verändert, was jeder Aufrufer zwischengespeichert hat. Ein tiefes Modul würde den Cache vollständig verbergen. Dieses hier legt ihn offen.

Design · vorgeschlagen
Martin Kleppmann Designing Data-Intensive Applications

Was ist das Schlimmste, das Zeit und Nebenläufigkeit dem antun können?

Der Cache hat keine definierte Ablaufzeit; deshalb kann ein Wert weiter ausgeliefert werden, obwohl ein späterer Schreibzugriff den Datensatz verändert hat. Es gibt weder TTL noch Write-Through. Wird ein fehlender Treffer als falsy Wert dargestellt, sorgt die Wahrheitsprüfung außerdem dafür, dass wiederholte Anfragen nach demselben nicht vorhandenen Benutzer erneut die Datenbank belasten. Der glückliche Pfad funktioniert, doch die relevanten Fehlerfälle sind nicht ausdrücklich modelliert.

Design · vorgeschlagen

Drei Meister, eine winzige Funktion, drei Fehler in unterschiedlicher Tiefe: ein Bug, für den heute noch ein Fix ausgeliefert wird, und zwei Designentscheidungen, die einen Vorschlag und ein Gespräch verdienen, statt still umgeschrieben zu werden. Ein einzelner Checklistenpunkt wird kaum alle drei sichtbar machen, weil sie nicht auf dieselbe Weise falsch sind. Die Jury legt sie offen, weil jedes Mitglied nach einer anderen Fehlerklasse sucht.

Die konkrete Suite dahinter - Review-Profile, Prüfungen und Beweisleitern - ist Teil unserer internen Methodik. Im Projekt bleiben Kriterien, Befunde und Belege für Sie transparent. Und die zentrale Idee dürfen Sie mitnehmen: Nennen Sie den Meister und setzen Sie ihn dorthin, wo der Code sein Lebenswerk berührt.

Die Disziplin

Meinungen sind keine Urteile

Ein Raum voller starker Meinungen ist nur eine belesenere Art, falschzuliegen. Also bekommen die Meinungen nicht das letzte Wort; die Belege bekommen es. Laufzeitbeobachtungen, Tests, statische Analyse und fachliche Begründung beantworten unterschiedliche Fragen. Wir gewichten den direktesten reproduzierbaren Beleg für das jeweilige Risiko am höchsten.

Andersons Verdacht gegen diese Abfrage ist noch kein Befund. Ein gezielter Test, der eine präparierte id übergibt und Datensätze außerhalb des angefragten Benutzers erhält, macht daraus einen reproduzierbaren Beleg. Dann kann das Gespräch von Geschmack zu einem beobachteten Ergebnis wechseln. Wo es zählt, messen wir, statt uns auf Schätzungen zu verlassen, reproduzieren vor einer Behauptung und nutzen relevante Grenzfälle, um die Schwelle festzulegen, die in den Code wandert.

Das Gesetz

Schonungslos zum Code, sanft zum Menschen

Es gibt ein weiteres Mitglied der Jury, und es steht über allen anderen. Es hat keine Meinung zu Caches oder SQL. Es regelt, wie alles, was die anderen finden, gesagt werden darf.

„Systeme und Artefakte kritisieren, niemals Menschen."

Das eine Gesetz, das jedes Review bindet. Nach Rosenberg, Dekker, Edmondson.

Die Einheit der Kritik ist immer eine Sache: eine Zeile, ein Schema, eine Abfrage. Nie ein Mensch. Das ist keine Höflichkeit, die man an die Strenge schraubt. Es ist Teil der Strenge. Ein Review, das beschämt, fühlt sich nicht nur schlecht an; es funktioniert schlecht. Angst lässt Fehler nicht verschwinden. Sie lässt sie verstummen, und das nächste Audit findet weniger, nicht weil weniger da wäre, sondern weil die Leute gelernt haben, nicht mehr darauf hinzuweisen.

Also kommt jeder Befund in derselben Form heraus: was die Beweise zeigen, was es kostet, welchen Standard es verfehlt, und ein konkreter nächster Schritt, als Empfehlung angeboten; die konkrete Umsetzung bleibt in den Händen der Autorin oder des Autors. git blame ist eine Zeitmaschine, um zu verstehen, warum eine Zeile existiert, kein Gericht, um zu entscheiden, wer für sie geradestehen muss. Wir nehmen an, dass fähige Menschen mit dem, was sie wussten, ihr Bestes taten, weil das fast immer der Fall ist.

Warum die Toten

Der Kanon ist Kompression

Warum zu Menschen greifen, die ihr bestes Werk schufen, bevor manche unserer Entwicklerinnen und Entwickler geboren waren? Weil der Kanon Kompression über Jahrzehnte ist. Brooks erlebte, wie ein Großrechnerprojekt seine Pläne überzog, und hielt fest, was er daraus lernte; Jahrzehnte später kehren viele derselben Muster in neuen Sprachen und Organisationen wieder.

Manche Softwaremoden verblassen in wenigen Jahren. Die Klassiker bleiben nützlich, weil sie sich mit tieferen Kräften beschäftigen als mit dem Framework der Saison. Ein Meister ist eine Wette mit langer Erfolgsgeschichte. Wenn wir ein Review an einem von ihnen verankern, sind wir nicht nostalgisch. Wir nutzen gesammelte Erfahrung, damit Ihr Projekt sie nicht zu unnötigen Kosten neu entdecken muss.

Das ist die Methode: ein Regal, ausführbar gemacht. Wenn wir Software prüfen, von der Ihr Geschäft abhängt, ist die Qualität nicht von der Tagesform einer einzelnen Person abhängig. Mehrere bewährte Perspektiven greifen ineinander, und jeder Befund wird auf reproduzierbare Belege und geschäftliche Auswirkungen zurückgeführt.

Sie übernehmen, modernisieren oder stabilisieren eine Codebasis? Erzählen Sie uns, wo Risiken oder Reibung entstehen - dann besprechen wir, welche Prüfung zuerst Wert schafft.

← Alle Artikel

KONTAKT

Let's work together

Kontaktieren Sie uns und entdecken Sie digitale Lösungen, die Ihr Unternehmen voranbringen.

OFFICEBlücherstrasse 32, 75177 Pforzheim