
Hallo Habr!
Es gibt kein Ende, über
sauberen Code zu sprechen, aber der nächste Artikel von Dave Nicoletta ist sehr metaphorisch und hoffentlich wirklich übersetzungswürdig. Lassen Sie es ein wenig „erbaulich“ sein, da der Autor die Leser im Originalartikel im Voraus warnt.
Viel Spaß beim Lesen.
Zu Hause hat sich im Laufe der Jahre eine schlechte Angewohnheit durchgesetzt. Mit jedem Werkzeug haben wir immer wieder vergessen, es an seinen Platz zu setzen. Wenn jemand es das nächste Mal brauchte, musste er mehr Zeit damit verbringen, nach einem Werkzeug zu suchen, als ein Problem zu lösen. Das Traurigste ist, dass selbst derjenige, der das Instrument zuletzt genommen und irgendwo hingeworfen hat, zu genau denselben Suchen verurteilt war. Es stellte sich oft heraus, dass es schneller war, neue Geräte zu kaufen, als nach dem Werkzeug zu suchen, das wir haben - wir wissen es mit Sicherheit! - Irgendwo herumliegen.
Also haben wir vier mittelgroße Kreuzschlitzschraubendreher von Philips, drei mit flachem Schlitz, ein paar zusätzliche Zangen und Schraubenschlüssel sowie Adaptersätze. Ganz zu schweigen von der beeindruckenden Sammlung von Stiften, Klebebändern, Batterien und anderen guten Dingen, die überall verstreut sind.
Einmal haben wir uns entschieden: das reicht! Ordnete ihren Platz für alle Dinge und ordnete die Dinge mit unserem Inventar. Übergebene Werkzeuge für wohltätige Zwecke gespendet. Wir haben alle Anstrengungen unternommen, um Selbstdisziplin zu fördern, und Werkzeuge immer erst an ihre Stelle gesetzt, nachdem wir mit ihnen gearbeitet haben. Die Qualität und das Arbeitsvolumen pro Zeiteinheit stiegen stark an. Der Stress, das verschwendete Geld und die verdorbene Stimmung wurden viel weniger.
Bestellung in der Firmengarage aufgeben
Was wäre, wenn Automechaniker, die in einer Firmengarage arbeiten, überall Werkzeuge abwerfen würden? Sie würden mehr Zeit damit verbringen, nach Werkzeugen zu suchen, als tatsächlich zu arbeiten. Details würden an die falsche Stelle gebracht, verloren, verrostet, verwöhnt, sie würden einfach gestohlen. Die Lieferkosten würden stark steigen.
Es würde mehr Zeit in Anspruch nehmen, um die Aufgaben zu erledigen, aber die Qualität der Arbeit würde abnehmen. Wenn ein Mechaniker mit rostigen, abgenutzten und kaputten Werkzeugen arbeiten muss, ist es für ihn schwierig, Teile richtig zu montieren und zu befestigen. Darüber hinaus wirkt sich die Gewohnheit, in der Werkstatt ein Durcheinander zu arrangieren, zwangsläufig auf die Qualität der Arbeit aus.
Kunden haben genug von endlosen Endjob-Transfers. Bald werden sie zu zuverlässigeren Werkstätten gehen. Irgendwie ohne dich auskommen. Vielleicht sind die Analogien zur Softwareentwicklung und -unterstützung bereits offensichtlich.
Ordnung in die Softwareentwicklung bringen
Schauen wir uns ein konkretes Beispiel an: inkrementelles Refactoring.
Dieser Ausdruck ist für viele rätselhaft. Ich weiß nicht, welches Wort sie verwirrt: "inkrementell" oder "refactoring".
Inkrementelles (schrittweises) Refactoring unterscheidet sich grundlegend von groß angelegten. Vielen scheint es, dass jedes Refactoring notwendigerweise „großflächig“ ist, dass es von jemandem „autorisiert“ werden muss und daher die Arbeit angeblich herausgezogen werden muss. In der Tat ist alles erheblich verzögert, wenn das Refactoring im Laufe der Arbeit vernachlässigt wird.
Die meisten technischen Trainer, einschließlich mir, erklären den Unterschied in diesem Fall kaum; nicht weil dieser Unterschied per Definition kompliziert ist, sondern weil es wirklich schwierig ist, ihn in Worten zu formulieren. Ich denke jedoch, dass die Gewohnheit, das verfügbare Inventar sorgfältig zu prüfen und das Angebot zu überwachen, in diesem Fall eine gute Analogie ist.
Allmähliches Refactoring
Das schrittweise Umgestalten ist wie das Aufrechterhalten der Ordnung auf einer Werkbank auch auf der Höhe der Arbeit. Verwenden Sie einen Schraubendreher - setzen Sie ihn ein. Wir werden nicht vor jeder neuen Aufgabe eine Werkstatt dafür wieder aufbauen. Der Punkt ist vielmehr die Fähigkeit zu beenden ... wie man beendet, was Sie begonnen haben. Die Enden abstreifen.
Das schrittweise Umgestalten nimmt nicht viel zusätzliche Zeit in Anspruch und erfordert keine Erlaubnis von oben. In diesem Fall müssen Sie um Erlaubnis bitten, den Code nicht zu bereinigen, wenn Sie sich beeilen müssen. Die Fähigkeit, den Code ständig sauber zu halten, sollte in der Tat als die grundlegende berufliche Fähigkeit eines Programmierers angesehen werden. Es ist eine Schande, dass "sauberer Code" heute Propaganda braucht, und einige Programmierer lehnen es sogar ab, solche Reinheit zu bringen. Das schrittweise Refactoring hat absolut nichts mit einem groß angelegten architektonischen Refactoring zu tun, das wirklich sorgfältige Planung erfordert und dafür Zeit, Geld und Mitarbeiter bereitstellt.
Pfadfinderregel
Bei der Programmierung gibt es eine sogenannte „Scout-Regel“: Halten Sie den Code mindestens so sauber, wie er empfangen wurde. Gleiches gilt für die Aufbewahrung von Arbeitsgeräten zu Hause. Wenn wir nach einer Zange suchen, aber bemerken, dass der Schlitzschraubendreher versehentlich am Kreuz und der Kreuzschraubendreher am Schlitz angekommen sind, setzen wir sie dabei an ihre Stelle. Wir brauchen dazu keine offizielle Genehmigung.
So funktioniert schrittweises Refactoring. Vor uns liegt ein Teil des Codes, und wir müssen der Liste der verfügbaren Konstruktionen eine neue Bedingung hinzufügen. Wir stellen fest, dass die Liste als großer if / else-Block implementiert ist. Wir entscheiden, dass es als Schalter oder Auswahloperator neu gestaltet werden muss, während eine Bedingung hinzugefügt wird. Man kann argumentieren: Ist das wirklich viel besser als der if / else-Block? Ja, Sie haben Recht: nicht viel. Aber ein bisschen besser. Wenn jemand diesen Code das nächste Mal nach Ihnen liest, kann er ihn noch besser verfeinern, da Sie seine Startposition verbessert haben. Wenn Sie so etwas schon einmal gemacht haben, haben Sie wahrscheinlich bemerkt, dass Sie beim sorgfältigen Lesen aller Bedingungen manchmal doppelte Konstruktionen gefunden haben, dann die nicht optimale Reihenfolge der Ausdrücke. Vielleicht sind Sie auf eine Bedingung gestoßen, die niemals erfüllt werden kann, oder sogar auf ein logisches „Loch“, durch das die gesamte Steuersequenz durch den if / else-Block fällt und in einigen Fällen überhaupt nicht verarbeitet wird. Freuen Sie sich nur, dass Sie es jetzt und nicht spät in der Nacht entdeckt haben, wenn Sie ein entsprechendes Ticket vom technischen Support erhalten. In einem solchen Moment, in dem die Augen zusammenhalten, besteht absolut keine Lust, den verwirrten Code zu verstehen.
Vielleicht werden wir der Anwendung einige neue Funktionen hinzufügen und feststellen, dass die Funktion / Methode, die wir geschrieben haben, einer anderen (anderen) sehr ähnlich ist, die wir bereits in der Codebasis haben. Nach nur wenigen Sekunden werden wir solche Duplikate auch ohne die zusätzlichen Tools, die bei unseren Diensten in schicken IDEs angeboten werden, beseitigen. Sie können ohne zu zögern umgestalten, da wir uns an Selbstdisziplin gewöhnt haben und garantieren, dass bereits Mikrotests (Unit-Tests) für diesen Fall geschrieben wurden. Dann ist manuelles Refactoring nicht schrecklich. Überlegen Sie sich am Ende mindestens einen Grund, warum nicht?
"Langfristig" ist normalerweise nicht so lange, wie es scheint
Oft höre ich von verschiedenen Leuten, dass Refactoring „langfristige“ Vorteile bringt. Obwohl es theoretisch hier in der realen Welt ist, muss man die Arbeit ständig streng übergeben. Wenn wir jedoch davon sprechen, die Reinheit des Codes durch ein kleines schrittweises Refactoring aufrechtzuerhalten, dauert das „Langzeit“ genau bis zu dem Moment, an dem jemand anderes die Codebasis berührt. Genau bis zum nächsten Mal.
Die schlechte Nachricht ist, dass das Gegenteil der Fall ist. Wenn Sie den Code während der Arbeit nicht bereinigen, verschlechtert er sich schnell. Wir haben keinen zehnjährigen „Airbag“, der es uns ermöglichen würde, ungestraft eine Ehe aufzubauen, bis die Probleme beginnen. Die nächste Änderung, die vorgenommen werden muss, wird unannehmbar lange dauern, das Risiko einer Code-Regression wird zunehmen und die Situation ohne angemessene Beachtung wird sich nur verschlechtern.
Wenn wir nur hacken, um den Wunsch des Kunden zu befriedigen (und er das fertige Produkt schneller haben möchte), wie werden wir diese Anforderungen weiterhin erfüllen, nachdem wir sichergestellt haben, dass keine schnellen Änderungen mehr vorgenommen werden, da wir den Code in den Status gebracht haben Verwirrung, und es ist unmöglich, es aufrechtzuerhalten?
Was ist schnell, was ist langsam?
Kunden möchten immer, dass Sie härter arbeiten, egal wie schnell Sie arrangieren. Der effektivste Weg, um die Zeit bis zur Veröffentlichung zu verkürzen, besteht darin, alles richtig zu machen. gut machen; Reinigen Sie die Enden ständig, ausnahmslos. Um die Geschwindigkeit zu erhöhen, werden wir in der Praxis nur langsamer und nicht in der kurzlebigen „langfristigen Perspektive“, sondern hier und jetzt.
Wenn der Kunde verlangt, dass Sie schneller arbeiten, bedeutet dies nicht, dass er Ihnen erlaubt, nachlässig zu arbeiten. Natürlich scheint es ihm offensichtlich, dass er uns nicht nach jeder Anfrage daran erinnern sollte, dass er an hoher Qualität interessiert ist. Hohe Qualität ist einer der Bestandteile unserer Arbeit.
Als Ingenieure entscheiden wir selbst, ob wir das schrittweise Refactoring als Grundelement unserer beruflichen Tätigkeit betrachten. Wir fragen nicht, ob wir so arbeiten können, wie es sollte, so wie der Chirurg den Buchhalter nicht fragt, ob er Zeit hat, sich vor der Operation die Hände zu waschen. Die für die Operation aufgewendete Zeit entspricht genau der Zeit, die für den Erfolg der Operation erforderlich ist. Dem Patienten muss der Anhang sorgfältig entfernt werden, und nach der Entlassung kann die Person zum normalen Leben zurückkehren - ohne Wundinfektion und ohne Tampon im Bauchraum. Es wird nur schlimmer, wenn eine Person zehn Minuten früher als nötig aus dem Operationssaal entfernt wird und dann Komplikationen auftreten.
In diesem Fall parieren sie oft, dass wenn „alles gemäß der Wissenschaft gemacht wird“, es sich als „zu lang“ herausstellt. Nein, in der Tat ist „zu lang“ die Zeit, die benötigt wird, um die Konsequenzen zu korrigieren, wenn die Arbeit in Eile und ohne die richtige Professionalität erledigt wurde. Die Erholung von einer Infektion ist ein echter Schock für den Patienten und seine Familie. Dies wirkt sich unweigerlich auf seine Arbeit aus. Eine zweite Operation, bei der ein vergessener Tampon aus dem Bauch herausgeschnitten werden muss, ist eine viel schwerwiegendere Intervention und wird nur erforderlich sein, weil die Person zum ersten Mal in Eile operiert wurde.
Wenn Sie beim Programmieren fünf Regressionen des Codes vornehmen müssen, weil jemand ihn in Eile geschrieben hat, können Sie nicht von "Zeit sparen" sprechen. Im Gegenteil, Änderungen werden länger vorgenommen. Die Arbeit wird erst erledigt, wenn sie korrekt ausgeführt wurde. Wenn das Team Stunden und Tage damit verbringen musste, Fehler nach der „Entwurfsbereitschaft“ zu korrigieren, ist dies Zeitverlust, der für andere nützliche Arbeiten aufgewendet werden könnte. Dies ist ein entgangener Gewinn.
Solche Fehler haben wellenförmige Konsequenzen und führen zu langfristigen Zeit- und Geldverlusten und manchmal zum Verlust von Kunden. Zusätzlicher Stress fällt auf die Schultern der Ingenieure selbst; niedrige Moral, hohe Fluktuation. Daher eine immer härtere Verschraubung und eine weitere Abnahme der Moral und der Beteiligung an der Arbeit.
Technische Schulden als Metapher
Wann immer Sie sich dem Thema des schrittweisen Refactorings zuwenden, wird Sie definitiv jemand an technische Schulden erinnern. Sie werden sagen: "Wir haben eine solche Frist, dass es nur notwendig ist, Abstriche zu machen." Sie werden hinzufügen, dass in diesem Fall das Team bewusst technische Schulden ansammelt, die sich an den Bedürfnissen des Unternehmens orientieren.
Diejenigen, die dies sagen, verstehen diese Metapher nicht und vielleicht überhaupt keine Metaphern.
Die Metapher soll keine vollständige und umfassende Beschreibung der zu charakterisierenden Sache sein.
Eine Metapher hilft im Allgemeinen dabei, einen Eindruck von einem Aspekt dieser Sache zu vermitteln.
Menschen neigen dazu, ein Ding durch seine Metapher zu ersetzen und dann mit einer Metapher zu operieren, als ob sie und
das beschriebene ist ein und dasselbe. Nein, das ist nicht dasselbe. Der Punkt.
Darüber hinaus ist es üblich, dass Menschen eine Metapher über ihren ursprünglichen Kontext hinaus breit interpretieren. Dadurch wird die Bedeutung der Metapher verwischt und sie wird immer weniger nützlich.
Ward Cunningham schlug eine Metapher für technische Schulden vor, die Kundeninteraktionen in der Finanzbranche beschreibt. Er suchte nach einer geeigneten Metapher für diesen speziellen Kontext, um zu betonen, wie die schrittweise Realisierung von Chancen dazu beiträgt, eine Rückkopplungsschleife zu schaffen, in der das Programm ständig optimiert wird. Er meinte nicht "Ecken abschneiden, um die Illusion einer schnellen Entwicklung zu erzeugen".
Das ursprüngliche Konzept der Metapher für technische Schulden implizierte, dass der Code notwendigerweise sauber gehalten wurde. Personen, die das im Code verbleibende Problem verstehen, bewegen sich Schritt für Schritt in Richtung seiner Lösung, und der Code ist immer genau genug, damit solche schrittweisen Verbesserungen daran vorgenommen werden können. Es ist nicht die Tatsache, dass einige technische Gründe rechtfertigen können, warum der Code Junk ist und ständige Korrekturen erfordert.
Das Abschneiden von Ecken, um die Arbeit schnell zu übergeben, ist keine Anhäufung technischer Schulden. Dies ist ein häufiger Hack.
Wer ist verantwortlich?
Um eine schnelle Lieferung zu erreichen, müssen Sie Probleme bei der Arbeit beseitigen. Eines dieser Probleme ist Junk-Code. Sie können dieses Hindernis Schritt für Schritt beseitigen, indem Sie lernen, Selbstdisziplin zu üben. In diesem Fall spielt es keine Rolle, wie Sie arbeiten - nach dem "Wasserfall" -Modell oder nach der "Aggail". Wir selbst entscheiden, wie wir arbeiten, wenn wir die Tastatur berühren.
Ich fasse zusammen. Wenn Sie richtig arbeiten, einschließlich der Bereinigung der Enden, profitieren nur der Kunde, die Sponsoren, die Manager, diejenigen, die unseren Code in Zukunft unterstützen, und natürlich wir selbst.