Warum Code Review in Kotlin mehr ist als "Ich hätte es anders geschrieben"
\n\nEin Code Review (oder Code-Review) ist ein heiliges Ritual in jedem seriösen Team. Doch wenn es um Kotlin geht, geraten viele Entwickler ins Stocken. "Hier ist doch alles so prägnant!", "Nun, es ist ja eine expression-basierte Sprache" – denken Sie, während Sie den Pull-Request überfliegen. Und das ist ein Fehler.
\n\nKotlin ist elegant, aber tückisch. Es bietet Ihnen mächtige Werkzeuge: Scope-Funktionen, Sealed Classes, Coroutinen. Und genauso viele Möglichkeiten, sich ins Knie zu schießen. In diesem Artikel analysieren wir, worauf Sie bei einem Code Review in Kotlin wirklich achten müssen, damit Ihr Code nicht zu einem "Spaghetti-Monster" mit nullable Seiteneffekten wird.
\n\nDieser Artikel ist kein Syntax-Lehrbuch. Es ist eine lebendige Checkliste für Reviewer, die nicht nur funktionierenden, sondern wartbaren und sicheren Code sehen wollen.
\n\n1. Null Safety: Wenn "?" kein Allheilmittel ist
\n\nKotlin ist stolz auf seine Null Safety. Zu Recht. Aber beim Code Review müssen Sie nicht nur das Vorhandensein von "!!" prüfen, sondern die gesamte Logik im Umgang mit nullable-Typen.
\n\nWas sollte Sie sofort alarmieren?
\n\n- \n
- Unkontrollierte Verwendung von "!!". Wenn ein Entwickler
!!setzt, muss er im Kommentar erklären, warum dieser Wert garantiert nicht null ist. Fehlt die Erklärung, ist es ein Bug. \n - Ketten aus safe call (?.) und elvis (?:). Sie kaschieren oft logische Fehler. Beispiel: \n
// Problem: Wenn user?.address?.city == null ist,\n// geben wir still "Unknown" zurück, ohne zu loggen\nval city = user?.address?.city ?: "Unknown"\n\n\nWie sollte es sein? Wenn null eine Ausnahmesituation ist, verwenden Sie requireNotNull oder checkNotNull. Wenn es normales Verhalten ist, loggen Sie es.
val city = user?.address?.city\n ?: run {\n logger.warn("Benutzer $userId hat keine Stadt")\n "Unknown"\n }\n\n\nFragen Sie bei jedem Code Review in Kotlin: "Was ist, wenn dieser null ein Bug ist, den wir gerade verschweigen?"
\n\n2. Scope-Funktionen: let, apply, run – mit Bedacht einsetzen
\n\nScope-Funktionen sind die Stärke von Kotlin. In der Praxis sehe ich jedoch, wie sie als Hammer für jeden Nagel verwendet werden. Eine Kotlin Code-Überprüfung sollte die Frage beinhalten: "Warum genau let und nicht run?"
Typische Stolperfallen:
\n\n- \n
- let für die Null-Prüfung. Okay, aber verschachteln Sie sie nicht ineinander: \n
// Schrecklich\nuser?.let { u ->\n address?.let { a ->\n process(u, a)\n }\n}\n\n// Gut\nif (user != null && address != null) {\n process(user, address)\n}\n\n\n- \n
- apply zur Objekt-Mutation. Das ist sein natürlicher Einsatzzweck. Aber wenn Sie
applyinnerhalb vonletverwenden – Stopp. Das riecht nach Spaghetti-Code. \n
Denken Sie daran: with dient der Gruppierung von Aufrufen, also für Seiteneffekte (Logging), run für Berechnungen im Kontext. Verwechseln Sie sie nicht.
3. Unveränderlichkeit: var ist ein rotes Tuch
\n\nKotlin propagiert val. Und das ist großartig. Aber bei Kotlin Code-Reviews sehe ich oft, wie Entwickler var schreiben, wo val mit Kopieren ausgereicht hätte.
// Schlecht\nvar result = mutableListOf<Int>()\nitems.forEach { result.add(it * 2) }\n\n// Gut\nval result = items.map { it * 2 }\n\n\nDie Regel ist einfach: Wenn Sie var sehen, fragen Sie: "Warum nicht val?" Meistens werden Sie überrascht sein: "Darüber habe ich nicht nachgedacht."
Eine Ausnahme besteht nur, wenn Mutation wirklich notwendig ist (z. B. in Schleifen mit Akkumulation). Aber auch dort kann man oft durch fold oder reduce ersetzen.
4. Sealed Classes und when: Vergessen Sie nicht das else
\n\nSealed Classes sind eine elegante Alte