Hallo, Freunde. Vor dem Start des Kurses , teilen wir traditionell mit Ihnen die Übersetzung eines nützlichen Materials.
Software löst immer mehr alltägliche Aufgaben und wird dabei immer komplexer. Wie Mark Andreessen einmal sagte, sie übernimmt die Welt.

In den letzten Jahren haben sich die Ansätze zur Entwicklung und Bereitstellung von Anwendungen erheblich verändert. Es gab tektonische Verschiebungen, die zur Entstehung eines Sets von Prinzipien führten. Diese Prinzipien haben sich als nützlich erwiesen, um Teams zu formen, Design, Entwicklung und die Bereitstellung Ihrer Anwendung an Endbenutzer zu gestalten.
Die Prinzipien lassen sich wie folgt zusammenfassen: Die Anwendung sollte klein, netzwerkorientiert und entwicklerzentriert sein.Auf Grundlage dieser drei Prinzipien können Sie eine zuverlässige, umfassende Anwendung erstellen, die schnell und sicher an den Endbenutzer ausgeliefert werden kann und zudem leicht skalierbar und erweiterbar ist.

Jedes der genannten Prinzipien hat verschiedene Aspekte, die wir erörtern werden, um zu zeigen, wie jedes Prinzip zur Erreichung des Endziels beiträgt: die schnelle Bereitstellung zuverlässiger, einfach zu wartender und benutzerfreundlicher Anwendungen. Wir werden die Prinzipien im Vergleich zu ihren Gegensätzen betrachten, um beispielsweise zu verdeutlichen, was "Stellen Sie sicher, dass Sie verwenden" bedeutet. Prinzip der Kleindimensionierung».
Wir hoffen, dass dieser Artikel Sie dazu ermutigt, die vorgeschlagenen Prinzipien für den Aufbau moderner Anwendungen zu nutzen, die einen einheitlichen Ansatz im Design im Kontext des kontinuierlich wachsenden Technologiestacks bieten.
Indem Sie diese Prinzipien anwenden, werden Sie feststellen, dass Sie die neuesten Trends in der Softwareentwicklung nutzen, einschließlich des Ansatzes für die Entwicklung und Bereitstellung von Anwendungen, die Nutzung von Containern (zum Beispiel, ) und Frameworks zur Orchestrierung von Containern (wie zum Beispiel, ), der Einsatz von Mikrodiensten (einschließlich der Mikrodienstarchitektur und für Mikrodienstanwendungen.
Was ist eine moderne Anwendung?
Moderne Anwendungen? Moderner Stack? Was bedeutet eigentlich 'modern'?
Die meisten Entwickler haben nur ein allgemeines Verständnis davon, woraus eine moderne Anwendung besteht, deshalb ist es wichtig, diese Begrifflichkeit klar zu definieren.
Eine moderne Anwendung unterstützt mehrere Clients, sei es eine Benutzeroberfläche mit der JavaScript-Bibliothek React, eine mobile Anwendung für Android oder iOS, oder eine Anwendung, die sich über eine API mit einer anderen verbindet. Eine moderne Anwendung geht davon aus, dass es eine unbestimmte Anzahl von Clients gibt, für die sie Daten oder Dienstleistungen bereitstellt.
Eine moderne Anwendung stellt eine API zur Verfügung, um auf die angeforderten Daten und Dienstleistungen zuzugreifen. Die API sollte stabil und konsistent sein, anstatt speziell für einen bestimmten Client entwickelt zu werden. Die API ist über HTTP(S) zugänglich und bietet Zugriff auf alle Funktionen, die im GUI oder CLI vorhanden sind.
Daten sollten in einem gängigen, kompatiblen Format wie JSON verfügbar sein. Die API stellt Objekte und Dienste in einer verständlichen, strukturierten Form bereit, beispielsweise bieten RESTful APIs oder GraphQL eine angemessene Schnittstelle.
Moderne Anwendungen basieren auf einem zeitgemäßen Technologie-Stack, der diese Anwendungen unterstützt. Ein solcher Stack ermöglicht es Entwicklern, mühelos Anwendungen mit HTTP-Schnittstellen und klar definierten API-Endpunkten zu erstellen. Die gewählte Methode erleichtert es Ihrer Anwendung, Daten im JSON-Format zu empfangen und zu senden. Mit anderen Worten, der moderne Stack entspricht den Komponenten des Twelve-Factor-Applications-Ansatzes. .
Beliebte Versionen dieses Stack-Typs basieren auf , , , , und . Mikroskopische Architektur veranschaulicht ein Beispiel für einen modernen Stack, der in jeder der genannten Sprachen implementiert ist.
Bitte beachten Sie, dass wir nicht ausschließlich einen mikrosystematischen Ansatz propagieren. Viele von Ihnen arbeiten mit Monolithen, die weiterentwickelt werden müssen, während andere mit SOA-Anwendungen zu tun haben, die sich weiterentwickeln, um zu mikrosystematischen Anwendungen zu werden. Drittens bewegen sich einige in Richtung serverloser (serverless) Anwendungen, während andere Kombinationen der oben genannten Ansätze implementieren. Die in diesem Artikel dargelegten Prinzipien sind auf jedes dieser Systeme anwendbar mit nur geringfügigen Anpassungen.
Prinzipien
Jetzt, wo wir ein gemeinsames Verständnis dafür entwickelt haben, was moderne Anwendungen und moderne Stacks sind, ist es an der Zeit, in die Prinzipien der Architektur und Entwicklung einzutauchen, die Ihnen bei der Entwicklung, Implementierung und Pflege moderner Anwendungen von großem Nutzen sein werden.
Eines der Prinzipien lautet: „Erstellen Sie kleine Anwendungen“. Lassen Sie uns einfach sagen, es sei das Prinzip der Kleinheit. Es gibt unglaublich komplexe Anwendungen, die aus einer Vielzahl von beweglichen Komponenten bestehen. Das Design einer Anwendung aus kleinen diskreten Komponenten erleichtert jedoch die Planung, Wartung und den Betrieb insgesamt. (Beachten Sie, wir haben „erleichtert“ gesagt und nicht „einfach gemacht“).
Das zweite Prinzip besagt, dass wir die Produktivität der Entwickler steigern können, indem wir ihnen helfen, sich auf die Funktionen zu konzentrieren, die sie entwickeln, und sie während der Umsetzung von den Sorgen um Infrastruktur und CI/CD befreien. Kurz gesagt, unser Ansatz ist entwicklerorientiert..
Schließlich sollte alles, was mit Ihrer Anwendung zu tun hat, mit dem Netzwerk verbunden sein. In den letzten 20 Jahren haben wir enorme Fortschritte in Richtung einer vernetzten Zukunft gemacht, da Netzwerke schneller und Anwendungen komplexer geworden sind. Wie bereits festgestellt, sollte eine moderne Anwendung von einer Vielzahl verschiedener Clients über das Netzwerk genutzt werden. Der Einsatz von Netzwerkdenken in der Architektur bietet erhebliche Vorteile, die gut mit das Prinzip der Kleinheit und dem Konzept des Ansatzes kombiniert werden, der sich an Entwicklern orientiert..
Wenn Sie bei der Entwicklung und Implementierung Ihrer Anwendung die genannten Prinzipien berücksichtigen, haben Sie einen unbestreitbaren Vorteil bei der Entwicklung und Bereitstellung Ihres Produkts.
Lassen Sie uns diese drei Prinzipien näher betrachten.
Das Prinzip der Kleinheit
Das menschliche Gehirn hat Schwierigkeiten, gleichzeitig eine große Menge an Informationen zu verarbeiten. In der Psychologie bezeichnet der Begriff kognitive Belastung die gesamte Menge an geistigen Anstrengungen, die erforderlich sind, um Informationen im Gedächtnis zu behalten. Die Verringerung der kognitiven Belastung für Entwickler hat oberste Priorität, da sie sich so auf die Lösung von Problemen konzentrieren können, anstatt ein komplexes Modell der gesamten Anwendung und der entwickelten Funktionen im Kopf zu behalten.

Anwendungen werden aus folgenden Gründen dekonstruiert:
- Verringerung der kognitiven Belastung für Entwickler;
- Beschleunigung und Vereinfachung von Tests;
- Schnelle Bereitstellung von Änderungen in der Anwendung.
Es gibt mehrere Möglichkeiten, die kognitive Belastung für Entwickler zu verringern, und hier kommt das Prinzip der Kleinheit ins Spiel.
Also, drei Möglichkeiten zur Verringerung der kognitiven Belastung:
- Die Zeitrahmen, die bei der Entwicklung neuer Funktionen berücksichtigt werden müssen, verkürzen – je kürzer der Zeitrahmen, desto geringer die kognitive Belastung.
- Die Menge des Codes, an dem gleichzeitig gearbeitet wird, reduzieren – weniger Code bedeutet weniger Belastung.
- Den Prozess zur Einführung inkrementeller Änderungen in die Anwendung vereinfachen.
Verkürzung der Entwicklungszeiträume
Lassen Sie uns zu der Zeit zurückkehren, als die Methodik waterfall der Standard im Entwicklungsprozess war und Zeitrahmen von sechs Monaten bis zwei Jahren für die Entwicklung oder Aktualisierung einer Anwendung gang und gäbe waren. In der Regel lasen die Ingenieure zunächst die entsprechenden Dokumente wie das Produktanforderungsdokument (PRD), das Systemreferenzdokument (SRD), den Architekturplan und begannen, all diese Informationen zu einer kognitiven Modell zu verbinden, nach dem sie den Code schrieben. Da sich die Anforderungen und damit auch die Architektur änderten, war es notwendig, erhebliche Anstrengungen zu unternehmen, um das gesamte Team über die Aktualisierungen des kognitiven Modells zu informieren. Ein solcher Ansatz konnte im schlimmsten Fall die Arbeit vollständig lahmlegen.
Die größte Veränderung im Prozess der Anwendungsentwicklung war die Einführung der agilen Methodik. Eine der wesentlichen Eigenschaften dieser Methodik agil ist die iterative Entwicklung. Dies führt zu einer Verringerung der kognitiven Belastung für die Ingenieure. Anstatt von den Entwicklern zu verlangen, eine Anwendung in einem langen Zeitraum zu realisieren, agil erlaubt dieser Ansatz, sich auf kleine Codeabschnitte zu konzentrieren, die schnell getestet und bereitgestellt werden können, während gleichzeitig auch Feedback eingeholt wird. Die kognitive Belastung der Anwendung hat sich von einem Zeitrahmen von sechs Monaten bis zu zwei Jahren, der eine enorme Anzahl von Spezifikationen umfasste, auf zweiwöchentliche Ergänzungen oder Änderungen von Funktionen verschoben, die auf ein amorphes Verständnis eines umfangreichen Programms ausgerichtet sind.
Der Fokus verschiebt sich von einer massiven Anwendung auf spezifische, kleine Funktionen, die innerhalb eines zweiwöchigen Sprints abgeschlossen werden können, wobei maximal eine Funktion des nächsten Sprints im Hinterkopf bleibt. Dies stellt eine wesentliche Veränderung dar. Es hat die Entwicklungseffizienz gesteigert, während die kognitive Belastung, die ständig schwankte, verringert wurde.
In der Methodologie agil wird davon ausgegangen, dass die endgültige Anwendung eine leicht veränderte Version des ursprünglichen Konzepts sein wird, weshalb der Schluss der Entwicklung zwangsläufig unklar ist. Nur die Ergebnisse jedes einzelnen Sprints können klar und präzise sein.
Kleine Codebasen
Der nächste Schritt zur Verringerung der kognitiven Belastung besteht darin, die Codebasis zu verkleinern. Moderne Anwendungen sind in der Regel umfangreich – eine zuverlässige, unternehmenskritische Anwendung kann aus Tausenden von Dateien und Hunderttausenden von Codezeilen bestehen. Je nach Organisation der Dateiverknüpfungen und Codeabhängigkeiten können diese offensichtlich oder im Gegenteil schwer zu erkennen sein. Selbst das Debuggen der Codeausführung kann problematisch sein, abhängig von den verwendeten Bibliotheken und davon, wie gut die Debugging-Tools zwischen Bibliotheken/Paketen/Modulen und Benutzercode unterscheiden.
Der Aufbau eines Arbeitsmodells für den Code einer Anwendung kann eine beträchtliche Zeit in Anspruch nehmen und erneut eine große kognitive Belastung für den Entwickler darstellen. Dies ist besonders typisch für monolithische Codebasen, in denen eine große Menge an Code vorhanden ist, dessen Interaktionen zwischen den funktionalen Komponenten nicht klar definiert sind und bei denen die Aufmerksamkeitsspannen oft verschwommen sind, da die funktionalen Grenzen nicht eingehalten werden.
Eine der effektiven Methoden zur Verringerung der kognitiven Belastung für Ingenieure ist der Übergang zu einer Microservices-Architektur. In einem Microservices-Ansatz konzentriert sich jeder Service auf einen bestimmten Funktionsbereich; dabei ist die Bedeutung des Services in der Regel klar definiert und verständlich. Die Grenzen des Services sind ebenfalls deutlich – denken Sie daran, dass die Kommunikation mit dem Service über APIs erfolgt, sodass Daten, die von einem Service generiert wurden, problemlos an einen anderen übertragen werden können.
Die Interaktion mit anderen Services ist normalerweise auf einige benutzerdefinierte Services und einige Provider-Services beschränkt, die einfache und saubere API-Aufrufe, wie beispielsweise über REST, verwenden. Dadurch wird die kognitive Belastung für den Ingenieur erheblich verringert. Die größte Herausforderung bleibt das Verständnis des Modells der Interaktion zwischen den Services und wie Transaktionen in mehreren Services stattfinden. Letztendlich reduziert die Nutzung von Microservices die kognitive Last, indem sie die Menge an Code verringert, klare Servicegrenzen definiert und das Verständnis der Beziehungen zwischen Benutzern und Anbietern fördert.
Kleine inkrementelle Änderungen
Der letzte Aspekt des Prinzips Kleinlichkeiten besteht im Änderungsmanagement. Für Entwickler besteht die besondere Versuchung darin, den Code zu betrachten (vielleicht sogar ihren eigenen, älteren Code) und zu sagen: „Das ist Mist, das müssen wir alles neu schreiben.“ Manchmal ist das die richtige Entscheidung, manchmal nicht. Es legt die Verantwortung für eine umfassende Modelländerung auf das Entwicklerteam, was wiederum zu einer erheblichen kognitiven Belastung führt. Besser ist es, wenn die Ingenieure sich auf die Änderungen konzentrieren, die sie im Laufe eines Sprints umsetzen können, um dann rechtzeitig die erforderlichen Funktionen schrittweise bereitzustellen. Das Endprodukt sollte einem zuvor geplanten Ansatz ähneln, jedoch mit einigen Anpassungen und Tests, um den Bedürfnissen des Kunden gerecht zu werden.
Beim Umschreiben großer Codeabschnitte kann es manchmal unmöglich sein, Änderungen schnell zu implementieren, da hier andere Systemabhängigkeiten ins Spiel kommen. Um den Änderungsfluss zu kontrollieren, kann die Technik des 'Feature Hiding' eingesetzt werden. Das bedeutet grundsätzlich, dass die Funktionalität in der Produktionsumgebung vorhanden ist, aber über Umgebungsvariablen (env-var) oder andere Konfigurationsmechanismen nicht zugänglich ist. Wenn der Code alle Qualitätssicherungsprozesse bestanden hat, kann er in einem versteckten Zustand in der Produktion landen. Diese Strategie funktioniert jedoch nur, wenn die Funktion letztendlich aktiviert wird. Andernfalls würde sie nur den Code überladen und zusätzliche kognitive Belastungen verursachen, mit denen der Entwickler umgehen muss, um produktiv zu bleiben. Das Änderungsmanagement und inkrementelle Änderungen helfen dabei, die kognitive Belastung der Entwickler auf einem handhabbaren Niveau zu halten.
Ingenieure stehen vor vielen Herausforderungen, selbst bei der einfachen Implementierung zusätzlicher Funktionen. Es wäre klug von der Unternehmensleitung, die unnötige Belastung des Teams zu reduzieren, damit es sich auf die Schlüsselaspekte der Funktionalität konzentrieren kann. Es gibt drei Maßnahmen, die Sie ergreifen können, um Ihr Entwicklerteam zu unterstützen:
- Verwenden Sie eine Methodik
agil, um den Zeitraum zu begrenzen, in dem sich das Team auf die wesentlichen Funktionen konzentrieren sollte. - Implementieren Sie Ihre Anwendung als mehrere Microservices. Dies verengt die Anzahl der einzuführenden Funktionen und stärkt die Grenzen, die die kognitive Belastung während der Arbeit aufrechterhalten.
- Bevorzugen Sie inkrementelle Änderungen gegenüber großen und komplexen Anpassungen, indem Sie kleine Codeabschnitte ändern. Nutzen Sie Funktionsverbergung, um Änderungen umzusetzen, selbst wenn diese nicht sofort nach der Implementierung sichtbar werden.
Wenn Sie in Ihrer Arbeit das Prinzip der Kleinheit anwenden, wird Ihr Team viel glücklicher, kann sich besser auf die notwendigen Funktionen konzentrieren und hat eine höhere Wahrscheinlichkeit, qualitativ hochwertige Änderungen schneller umzusetzen. Das bedeutet jedoch nicht, dass die Arbeit nicht komplexer werden kann; manchmal erfordert die Einführung neuer Funktionen Modifikationen mehrerer Dienste, und dieser Prozess kann schwieriger sein als in einer monolithischen Architektur. In jedem Fall sind die Vorteile des Ansatzes der Kleinheit das wert.
Ende des ersten Teils.
Bald werden wir den zweiten Teil der Übersetzung veröffentlichen, und jetzt freuen wir uns auf Ihre Kommentare und laden Sie zu , der heute um 20:00 Uhr stattfinden wird.
Quelle: habr.com
