Stimmen Sie nicht zu, das zu entwickeln, was Sie nicht verstehen



Seit Anfang 2018 bin ich der Leiter / Chef / Hauptentwickler im Team - nennen Sie es wie Sie wollen, aber unter dem Strich bin ich voll verantwortlich für eines der Module und für alle Entwickler, die daran arbeiten. Diese Position gibt mir einen neuen Blick auf den Entwicklungsprozess, da ich an mehr Projekten beteiligt bin und aktiver an der Entscheidungsfindung teilnehme. Dank dieser beiden Umstände wurde mir kürzlich plötzlich klar, wie sehr sich ein gewisses Maß an Verständnis auf den Code und die Anwendung auswirkt.

Der Gedanke, den ich ausdrücken möchte, ist, dass die Qualität des Codes (und des Endprodukts) eng damit zusammenhängt, wie sehr die Leute, die den Code entwerfen und schreiben, wissen, was sie tun.

Sie denken jetzt vielleicht: „Danke, Mütze. Natürlich wäre es schön zu verstehen, was Sie überhaupt schreiben. Andernfalls können Sie mit dem gleichen Erfolg eine Gruppe von Affen einstellen, um auf beliebige Schlüssel zu hämmern und sich darauf zu beruhigen. " Und du hast absolut recht. Dementsprechend halte ich es für selbstverständlich: Sie erkennen, dass eine allgemeine Vorstellung davon, was Sie tun, notwendig ist. Dies kann als Null-Verständnis-Ebene bezeichnet werden, und wir werden es nicht im Detail analysieren. Wir werden detailliert analysieren, was genau verstanden werden muss und wie sich dies auf die Entscheidungen auswirkt, die Sie jeden Tag treffen. Wenn ich diese Dinge vorher wüsste, würde ich eine Menge Zeitverschwendung und zweifelhaften Code sparen.

Obwohl Sie unten keine einzige Codezeile sehen werden, denke ich dennoch, dass alles, was hier gesagt wird, für das Schreiben von qualitativ hochwertigem, ausdrucksstarkem Code von großer Bedeutung ist.

Erste Ebene des Verständnisses: Warum funktioniert es nicht?


Entwickler erreichen dieses Niveau normalerweise in einem sehr frühen Stadium ihrer Karriere, manchmal sogar ohne Hilfe anderer - zumindest nach meinen Beobachtungen. Stellen Sie sich vor, Sie haben einen Fehlerbericht erhalten: Einige Funktionen in der Anwendung funktionieren nicht, Sie müssen sie beheben. Wie wirst du handeln?

Das Standardschema sieht folgendermaßen aus:

  1. Suchen Sie den Code, der das Problem verursacht (wie dies gemacht wird, ist ein separates Thema, das ich in meinem Buch über veralteten Code offenlege).
  2. Nehmen Sie Änderungen an diesem Snippet vor
  3. Stellen Sie sicher, dass der Fehler behoben ist und keine regressiven Fehler vorliegen

Konzentrieren wir uns nun auf den zweiten Punkt - Änderungen am Code. Es gibt zwei Ansätze für diesen Prozess. Erstens: Um zu untersuchen, was genau im aktuellen Code passiert, identifizieren Sie den Fehler und beheben Sie ihn. Zweitens: Bewegen Sie sich zur Berührung - fügen Sie beispielsweise +1 zu einer bedingten Anweisung oder Schleife hinzu, prüfen Sie, ob diese Funktion im richtigen Szenario funktioniert hat, und probieren Sie dann unendlich viel anderes aus.

Der erste Ansatz ist richtig. Wie Steve McConnell in seinem Buch "Code Complete" erklärt (ich kann es übrigens nur empfehlen), sollten wir jedes Mal, wenn wir etwas im Code ändern, sicher vorhersagen können, wie sich dies auf die Anwendung auswirkt. Ich zitiere aus dem Gedächtnis, aber wenn der Bugfix nicht wie erwartet funktioniert, sollte er für Sie sehr vorsichtig sein und Ihren gesamten Aktionsplan in Frage stellen.

Zusammenfassend muss man die gesamte Struktur des Codes und die Quelle eines bestimmten Problems verstehen, um einen soliden Bugfix durchzuführen, der die Qualität des Codes nicht beeinträchtigt.

Zweite Verständnisebene: Warum funktioniert es?


Diese Ebene wird viel weniger intuitiv verstanden als die vorherige. Als unerfahrener Entwickler habe ich es dank meines Chefs gelernt und später Anfängern wiederholt das Wesentliche erklärt.

Stellen wir uns diesmal vor, Sie haben zwei Fehlerberichte gleichzeitig erhalten: Der erste betrifft Szenario A, der zweite betrifft Szenario B. In beiden Szenarien stimmt etwas nicht. Dementsprechend werden Sie zuerst für den ersten Fehler genommen. Anhand der Prinzipien, die wir für die erste Ebene des Verständnisses eingeführt haben, vertiefen Sie sich in den für das Problem relevanten Code, finden heraus, warum die Anwendung in Szenario A genau so verhalten muss, und nehmen angemessene Anpassungen vor, die genau das Ergebnis liefern, das Sie erzielen erwartet. Alles läuft gut.

Dann gehen Sie zu Szenario B. Sie wiederholen das Skript, um einen Fehler zu provozieren, aber - eine Überraschung! - Jetzt funktioniert alles wie es sollte. Um Ihre Vermutung zu bestätigen, brechen Sie die Änderungen ab, die während der Bearbeitung des Fehlers A vorgenommen wurden, und der Fehler B kehrt erneut zurück. Ihre Fehlerbehebung hat beide Probleme gelöst. Glück!

Sie haben überhaupt nicht damit gerechnet. Sie haben eine Möglichkeit gefunden, den Fehler in Szenario A zu beheben, und Sie haben keine Ahnung, warum er in Szenario B funktioniert hat. In dieser Phase besteht die große Versuchung, zu entscheiden, dass beide Aufgaben erfolgreich abgeschlossen wurden. Das ist ganz logisch: Es ging darum, Fehler zu beseitigen, nicht wahr? Die Arbeit ist jedoch noch nicht abgeschlossen: Sie müssen noch herausfinden, warum Ihre Aktionen den Fehler in Szenario B korrigiert haben. Warum? Dann, dass er möglicherweise an den falschen Prinzipien arbeitet, und dann müssen Sie nach einem anderen Weg suchen. Hier einige Beispiele für solche Fälle:

  • Da die Lösung unter Berücksichtigung aller Faktoren nicht speziell auf Fehler B ausgerichtet werden konnte, ist die Funktion C möglicherweise unwissentlich fehlerhaft.
  • Es ist möglich, dass sich irgendwo auch der dritte Fehler versteckt hat, der sich auf dieselbe Funktion bezieht, und Ihr Bugfix bewirkt, dass das System in Skript B korrekt funktioniert. Jetzt sieht alles gut aus, aber eines schönen Tages wird dieser dritte Fehler bemerkt und behoben. Dann tritt in Szenario B erneut ein Fehler auf, und zwar nur dort.

All dies führt Zufälligkeit in den Code ein und eines Tages wird er Ihnen auf den Kopf fallen - höchstwahrscheinlich im ungünstigsten Moment. Sie müssen Ihren Willen zu einer Faust zusammenfassen, um sich zu zwingen, Zeit damit zu verbringen, zu verstehen, warum alles zu funktionieren scheint, aber es lohnt sich.

Dritte Ebene des Verständnisses: Warum funktioniert es?


Meine jüngsten Erkenntnisse hängen genau mit dieser Ebene zusammen, und es hätte mir wahrscheinlich die meisten Vorteile gebracht, wenn ich früher auf diese Idee gekommen wäre.

Schauen wir uns zur Verdeutlichung ein Beispiel an: Ihr Modul muss mit Funktion X kompatibel gemacht werden. Sie sind mit Funktion X nicht besonders vertraut, wurden jedoch darauf hingewiesen, dass Sie das F.-Framework verwenden müssen, um die Kompatibilität zu gewährleisten. Andere Module, die in X integriert sind, funktionieren genau mit ihm.

Seit dem ersten Tag Ihres Lebens ist Ihr Code überhaupt nicht mehr mit dem F-Framework in Kontakt gekommen, sodass es nicht so einfach ist, ihn zu implementieren. Dies hat schwerwiegende Folgen für einige Komponenten des Moduls. Trotzdem gehen Sie kopfüber in die Entwicklung: Schreiben Sie Code für Wochen, testen Sie, führen Sie Pilotversionen ein, erhalten Sie Feedback, beheben Sie Regressionsfehler, finden Sie unvorhergesehene Komplikationen, passen Sie nicht in den ursprünglich vereinbarten Zeitrahmen, schreiben Sie etwas mehr Code, testen Sie, erhalten Sie das Gegenteil Verbindung, korrekte Regressionsfehler - all dies, um das Framework F zu implementieren.

Und irgendwann merkt man plötzlich - oder hört vielleicht von jemandem -, dass das F-Framework Ihnen möglicherweise überhaupt keine Kompatibilität mit der X-Funktion bietet. Vielleicht war all diese Zeit und Mühe vollständig dazu.

Ähnliches geschah einmal bei der Arbeit an einem Projekt, für das ich verantwortlich war. Warum ist das passiert? Weil ich schlecht verstanden habe, was die Essenz von Funktion X ist und wie sie sich auf das Framework F bezieht. Was soll ich tun? Bitten Sie die Person, die die Aufgabe für die Entwicklung festlegt, klar zu erklären, wie der geplante Aktionsplan zum gewünschten Ergebnis führt, anstatt einfach zu wiederholen, was für andere Module getan wurde, oder das Wort zu nehmen, dass die Funktion X funktionieren muss.

Die Erfahrung dieses Projekts hat mich gelehrt, mich zu weigern, mit dem Entwicklungsprozess zu beginnen, bis wir ein klares Verständnis dafür haben, warum wir aufgefordert werden, bestimmte Aktionen auszuführen. Klartext ablehnen. Wenn Sie eine Aufgabe erhalten, besteht der erste Impuls darin, sie sofort aufzunehmen, um keine Zeit umsonst zu verschwenden. Die Politik, „das Projekt einzufrieren, bis wir alle Einzelheiten erfahren“, kann jedoch die Zeitverschwendung um Größenordnungen reduzieren.

Auch wenn sie versuchen, Druck auf Sie auszuüben, um Sie zu zwingen, mit der Arbeit zu beginnen, obwohl Sie nicht verstehen, wie dies gerechtfertigt ist, widerstehen Sie. Stellen Sie zunächst fest, für welchen Zweck Ihnen eine solche Aufgabe zugewiesen wurde, und entscheiden Sie, ob dies der richtige Weg zum Ziel ist. Ich musste das alles durch bittere Erfahrung lernen - ich hoffe, dass mein Beispiel für diejenigen, die dies lesen, das Leben leichter machen wird.

Vierte Verständnisebene: ???


In der Programmierung gibt es immer etwas zu lernen, und ich habe wohl nur die obersten Ebenen des Themas des Verstehens angesprochen. Welche anderen Ebenen des Verständnisses haben Sie im Laufe der Jahre der Arbeit mit Code entdeckt? Welche Entscheidungen wurden getroffen, die sich positiv auf die Qualität des Codes und der Anwendung auswirkten? Welche Entscheidungen haben sich als falsch erwiesen und Ihnen eine wertvolle Lektion erteilt? Teilen Sie Ihre Erfahrungen in den Kommentaren.

Source: https://habr.com/ru/post/de459588/


All Articles