Wie man mit altem Code rollt, wenn gestern ein Projekt benötigt wurde

Hallo. Mein Name ist Ivan Melnichuk, ich bin Leiter der Entwicklungsabteilung eines ukrainischen IT-Unternehmens. In der Veröffentlichung möchte ich meine persönlichen beruflichen Ansätze zur Lösung des Legacy-Code-Problems im Kontext der raschen Entwicklung des Projekts erläutern und über die Techniken berichten, auf die unser Team in Fällen zurückgreift, in denen „Funktionen für gestern übergeben werden müssen“.

Wir beschäftigen uns mit dem Projekt


Um zu vermitteln, wie genau, nachdenklich und mühsam die Arbeit mit dem Erbe sein sollte, werde ich eine Analogie mit einem Kartenhaus geben.

Bild

So sieht Legacy-Code aus. Wenn wir uns entscheiden, mindestens eine Karte aus diesem Gebäude zu entfernen oder zu ersetzen, laufen wir Gefahr, das gesamte Haus zu überwältigen und seine Überreste mit dem Boden in Einklang zu bringen.

Vermächtnis verhält sich ungefähr gleich. Daher sollte die Arbeit eines Programmierers, der die Aufgabe übernahm, das Projekt zu modernisieren und ihm ein zweites Leben einzuhauchen, in gewissem Maße Schmuck sein. Die meisten Programmierer versuchen, technische Schulden zu vermeiden und generell vom Thema abzuspringen. Sogar eine Hitparade der häufigsten Zitate zusammengestellt, die von Programmierern gehört werden mussten, die unter alten Bedingungen gefangen waren:

  1. Wir haben eine "einfache" Seite erstellt, und jetzt möchten Sie ein neues "Brötchen" erhalten, und wir müssen all dies neu schreiben, da wir Vermächtnis haben ...
  2. Niemand weiß, wie das funktioniert ..
  3. Um ein Modul hinzuzufügen, müssen Sie die gesamte Site überprüfen - nur auf diese Weise verstehen wir, was und wo es herauskommen kann ...
  4. Ich werde auf keinen Fall dorthin gehen, dort ist schon alles schlecht ...

Die Erfahrung in der Programmierung zeigt jedoch, dass ein Leben nach dem Erbe existiert. Es gibt keine Probleme mit der Programmierung. Es gibt nur Aufgaben, die angegangen werden müssen. Und bevor Sie einen Aktionsplan „zur Überwindung des Vererbungscodes“ erstellen, müssen Sie verstehen, wie schlimm das gesamte Projekt ist. Im Laufe der Praxis identifizierte er 6 Phasen des Projektproblems:

  1. Keine technische Dokumentation. Die niedrigste Schwelle für Probleme, da Sie testen und vorläufige Vermutungen anstellen können, wie dies funktionieren sollte.
  2. Keine Geschäftsdokumentation. Wenn die gesamte Dokumentation (sowohl technisch als auch geschäftlich) fehlt, entsteht unfreiwillig das Gefühl, „wir scheinen in der Geschichte zu stecken“. Selbst ein Unternehmen kann sich nicht erinnern, wie es funktionieren soll, was bedeutet, dass das Team zumindest kein Verständnis für das erwartete Ergebnis hat.
  3. Es gibt niemanden, der das entworfen hat. Wenn es neben der fehlenden Dokumentation auch keinen Entwickler gibt, der erklären könnte, wie das Projekt funktionieren soll, dann riecht es bereits gebraten.
  4. Wir wissen nicht, was der Benutzer letztendlich bekommen soll. Es ist eine Sache, wenn Fragen nur im Backend auftauchen, aber wenn wir immer noch absolut keine Ahnung haben, was auf der Vorderseite angezeigt werden soll, dann ist dies bereits nahe an dem Zustand „Der Patient ist eher tot als lebendig“.
  5. 200+ Nutzung jeder Funktion und sie heißen getA . Fünfter Schwierigkeitsgrad: Wenn Sie in Legacy einsteigen, sehen Sie die Verwendung von Funktion A und 200, und niemand weiß, warum es so ist ...
  6. Es gibt keine Programmierer, die sich entwickeln möchten / könnten. Keine Kommentare.

Geschäft verstehen


Geschäft zählt Geld. Unternehmen möchten keine zusätzlichen finanziellen Ressourcen ausgeben, um das zu wiederholen, was bereits funktioniert. Ein Unternehmen wird niemals die Idee kaufen: „Ich werde es auf eine neue Art und Weise tun, weil es mir nicht gefällt.“ Bieten Sie deshalb immer mehr an.

Oft treiben Entwickler das Geschäft zu nutzlosen Ideen. Bei dieser Gelegenheit gibt es einen separaten „Fund of Golden Quotes“.

  • Wir stellen ein neues Team für das hochwertige „Sägen“ des Codes ein. Das heißt, wir brauchen ein Team von Spezialisten, die das Projekt parallel zum bestehenden Team durchführen. Nicht die Tatsache, dass das Ergebnis anders sein wird, aber das Geschäft sollte bereits zwei Projekte enthalten.
  • Wir hören auf, Funktionen hinzuzufügen, jetzt nur noch Refactoring! Offiziell erklären Sie dem Geschäft: Absolutes Tabu in Bezug auf Funktionen, es ist nur möglich, "Dinge in Ordnung zu bringen". Inoffiziell sagten Sie, dass es keine umfangreichen Verbesserungen und Verbesserungen am Projekt geben wird, sondern nur lokal „reparieren“ wird.
  • Ich habe bereits alles, was ich in WP brauche. Ich muss nur die Datenbank migrieren. Dies ist ein „Symptom“ eines Anfängers. Junis Lieblingslied: Es ist eine so einfache Seite, dass es nur ein oder zwei Stunden funktioniert ...

Um mit dem Unternehmen über die Reinkarnation eines veralteten Codes zu verhandeln, der unter der Sauce neuer profitabler Funktionen bereitgestellt wird, ist es aus der Position heraus erforderlich, neue Geschäftshorizonte zu eröffnen. Vor den Verhandlungen müssen jedoch folgende Fragen beantwortet werden:

  1. Ist das Geschäft bereit zu wachsen? Sie müssen verstehen: Hat das Unternehmen eine Anfrage zur Erhöhung des Finanzstandards oder benötigt es nur den Service, um kompetenter zu arbeiten?
  2. Prototypenstadium? Oft bestellt ein Unternehmen einen einfachen Prototyp, mit dem es den Markt zum Zeitpunkt der Relevanz des Produkts „untersuchen“ möchte. Und nur wenn er anfängt, Geld zu verdienen, ist das Unternehmen bereit, die Funktion zu einem fortschrittlicheren und vollständigeren Projekt zu entwickeln.
  3. Entwicklung abgeschlossen und jetzt nur noch Unterstützung? Es ist wichtig, alle Aufgaben zu verstehen.
  4. Gibt es genug Feuer in unseren Augen und wird es nicht ausgehen? Das Projekt sollte inspirieren, nicht demotivieren. Es ist sehr wichtig, dass Ihr Team sich an der Reinkarnation von Legacy beteiligen möchte, da sich die Leute sonst allmählich in interessantere Projekte für sie zerstreuen.
  5. Gibt es einen Architekten? Dies ist die wichtigste Frage: Haben Sie eine Person, die die richtige Architektur erstellen und bereits guten Code schreiben kann? Es macht keinen Sinn, überhaupt zu versuchen, anzufangen, wenn es keinen Architekten gibt. Andernfalls werden Sie in einer Woche derjenige, der das Problem-Erbe erstellt hat.

Wenn Sie Ideen an Unternehmen verkaufen, konzentrieren Sie sich auf die Nachrichten "Neu, Erstellen, Hinzufügen" ... Das Unternehmen reagiert sehr gut auf Angebote aus der Serie: "Wir machen Sie zu einer neuen Funktion und Projekt X wird schneller ..." und "Um die Conversion zu erhöhen, fügen Sie eine neue hinzu ..." ”

P - Planung


Um schnell und effizient mit technischen Schulden arbeiten zu können, benötigen Sie einen Plan.

1. Definition von Aufgaben, bei denen wir parasitieren werden. Warum parasitieren? Es kommt oft vor: Wir haben ein Feature verkauft und damit teilweise Refactoring.

2. Definition von Anforderungen auf hoher Ebene. Es ist notwendig, eine eindeutige Geschäftsanfrage für einen „hohen Standard“ zu registrieren, um die korrekte Dokumentation zu erstellen.

3. Definition der Hauptmodule des Systems, Auferlegung von Modulen. Bevor Sie mit dem Refactoring beginnen, müssen Sie die Hauptmodule des Systems verstehen: Wo, wie, was und mit was kann der Code interagieren und in Abschnitte unterteilen.

4. Definition der Integration. Wenn wir ein bestimmtes Modul erstellen, müssen wir im Voraus darüber nachdenken, ob es in ein benachbartes Erbe eingebunden werden kann.

5. Teamdefinition. Einer im Refactoring-Bereich ist kein Krieger. Team ist ein sehr wichtiges Element für ein erfolgreiches Ergebnis. Leidenschaft, Teamgeist und exzellente Interaktion zwischen den Teilnehmern des Must-Have-Prozesses.

6. Wie werden wir testen? Wenn Sie ein qualitativ hochwertiges Projekt durchführen möchten, müssen Sie vorausdenken und Produkttests durchführen.

Neben dem oben Gesagten ist es auch wichtig, das gewünschte Endergebnis zu bestimmen, einen Skalierungsplan zu erstellen und die Engpässe des Projekts zu registrieren. Im Fall der Codeskalierung ist es beispielsweise wichtig zu verstehen, wo unter Hochlastbedingungen möglicherweise Probleme auftreten können (es kann sich um eine Datenbank, umfangreiche Abfragen, ein Raster oder eine andere Zwischenverbindung handeln, die „ausfallen“ kann).

Ebenso wichtig ist es, die Grenzen des Projekts zu bestimmen, wo es den alten Code gab und wo es eine neue Ebene des „Meisterwerks“ geben wird. Sie sollten auch Ansätze für Microservices oder DDD in Betracht ziehen, oder Sie benötigen möglicherweise etwas mehr „Nanomagie“.

Ninja Legacy-Techniken


Nach der „Vorarbeit“ kommen wir zu den Techniken, die den Prozess des Sparens technischer Schulden erleichtern. Ein universelles Rezept und Allheilmittel für alle Krankheiten in Legacy gibt es nicht, aber im Verlauf der Arbeit an Hochlastprojekten habe ich eine Liste von Zutaten erstellt, mit denen Sie einen wirklich „leckeren“ Code erstellen können.

1. Das Rad nicht neu erfinden. Für mich ist dies der wichtigste Hack im Leben, um Code zu schreiben. Alles wurde vor Ihnen erfunden. Tanzen Sie nicht mit Tamburinen und anderen Experimenten, um Probleme mit Legacy-Code zu lösen.

2. Der Code ist Standard. Ohne einen einzigen Standard schreibt jeder Entwickler auf seine eigene Weise. "Author's Style" wird zum Chaos beitragen und noch mehr Code-Müll verursachen.

3. Codeüberprüfung. Nicht nur eine Präsenz des Codestandards. Es ist auch notwendig, dass das Team für die Überprüfung verantwortlich war. Andernfalls kehrt alles zum Normalzustand zurück, dh zur Ebene des alten Codes.

4. Static Code-Analysatoren, PHP-Messdetektor usw. (anstelle von tausend Büchern) . Diese und andere automatische Techniken werden benötigt, um den Prozess zu beschleunigen, insbesondere mit demselben Überprüfungscode.

5. Wir versuchen Microservices. Separat kann es auch Module oder Bibliotheken geben. Warum Microservices? Ihr Vorteil besteht darin, die Logik so weit wie möglich zu isolieren und auf eine bestimmte API zu beschränken. Letzteres hat den Vorteil, dass die API im Vergleich zum „Adapter im Code, der repariert werden kann“ eine monolithischere Einheit ist. Die API hat jedoch einen Nachteil in Form zusätzlicher Netzwerkkosten.

6. Datenbankarchitektur, Datenquellen. Es ist die Datenbank, die ich als den ersten Engpass eines Vermächtnisses betrachte. Aber jeder entwirft, wie er will, und selbst in SQL können Sie unkonzentrierte Fehler finden. Hier einige Tipps zum Arbeiten mit der neuen Datenbank:

  • Scheiß auf nichts, Durst nach allem. Wenn Sie die alte falsche Datenstruktur schneller und produktiver in ein neues Datenformat ändern möchten, haben Sie zwei Möglichkeiten. Die erste besteht darin, eine neue Basis einzurichten und die alte vollständig zu entfernen, und was auch immer passiert. Die zweite - im Falle eines harten Erbes - führen Sie parallel ein neues Format ein. Im übertragenen Sinne, um einen neuen in der Nähe eines alten Baumes zu pflanzen. Warum ist der zweite Weg gerechtfertigt und vielversprechender? Da alles Neue effizient funktioniert und Probleme während der Bereitstellung oder in der Integrationsphase auftreten, können Sie den Code einfach zurücksetzen, und es ist nicht erforderlich, alle komplexen Datenbankmigrationen zurückzusetzen.
  • Eine neue Datenbank wird in der richtigen Struktur erstellt. Beim Erstellen einer neuen Ressource ist es wichtig, die Stellen zu steuern, an denen wir die neue Struktur schreiben. Parallel dazu ist es notwendig, Unterstützung für die alte Struktur zu schaffen, da es unpraktisch ist, sie vollständig loszuwerden. Das heißt, wir schreiben weiterhin neues Material und unterstützen gleichzeitig die alte Vorlage, in die wir alles Neue übersetzen, und lassen damit auch die alte arbeiten - wie auf die alte Art, aber die neue Struktur.
  • Wir kontrollieren die gesamte Aufnahme. Wir verpassen nicht die Details aus dem Bereich der Aufmerksamkeit, um die Unterstützung der Datenbank zu gewährleisten.

7. Aber SQL? Wenn Sie aus architektonischer Sicht mit Entitäten arbeiten können - arbeiten Sie. Das Konzept von etwas Bestimmtem und Endlichem hilft Ihnen dabei, keine unnötigen, doppelten Beziehungen zu erstellen.

8. Dekorateure, Adapter, Picks ... Diese Muster sind eines der wichtigsten für die Integration des neuen Codes in das alte Erbe.

9. Plan B oder Rollback-Plan für die Integration. Viele machen den Fehler, es zu vergessen. Es ist wichtig in der Situation, „wenn etwas schief geht“, wenn neues Material eingegossen wird. Das heißt, sobald wir mit dem Aufbau der Architektur beginnen, sollten wir bereits in diesem Stadium verstehen, wie wir sie im Falle eines Fehlers zurücksetzen werden.

10. Ein neuer Code ohne (Dock-) Tests wird in einer Woche zum Vermächtnis. Egal wie schön Ihr Code wäre, ohne Dokumentation in einer Woche befindet er sich im Status "Legacy" - aufgrund seiner Unverständlichkeit.

11. Testen. Wenn Unit-Tests zu teuer sind, verwenden wir Rauch-, Funktions- und Integrationstests. Wie realistisch ist es, Unit-Tests an ein Unternehmen mit Sauce zu verkaufen, um „einen Job schön zu machen“? In unserer Realität ist dies eher eine Seltenheit als ein Muster. Wenn es aus irgendeinem Grund mit „Einheiten“ nicht funktioniert, wenden wir uns Rauch-, Funktions- oder Integrationstests zu und vergessen auch nicht, dass wir die Aufgabe beispielsweise an einen manuellen Tester delegieren können.

Anstelle eines Nachworts


Das Wichtigste in dieser Geschichte ist, die Arbeit zu erledigen und nicht das Erbe von 6 problematischen Phasen (in der Reihenfolge von einfach bis komplex aufgelistet) zurückzulassen:

  • Keine technische Dokumentation
  • Keine Geschäftsdokumentation
  • Es gibt niemanden, der dies entwickelt hat
  • Wir wissen nicht, was der Benutzer erhalten soll.
  • 200 + Nutzung jeder Funktion und sie heißen getA ()
  • Es gibt niemanden, der dies entwickeln möchte / könnte.

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


All Articles