Die Architektur einer Unternehmensanwendung erfordert nicht nur technisches Wissen, sondern auch ein tiefes Verständnis für die Bedürfnisse und Herausforderungen des Unternehmens, für das die Anwendung entwickelt wird. In diesem Kapitel haben wir uns mit den grundlegenden Aspekten der Entwicklung einer Line-of-Business (LOB)-Anwendung befasst und dabei gezeigt, wie Angular als Framework genutzt werden kann, um eine robuste und skalierbare Lösung zu schaffen.

Das Beispiel der LocalCast Weather App hat uns die Grundlagen von Angular nähergebracht und gezeigt, wie man mit relativ wenig Code dynamische und performante Anwendungen entwickeln kann. Angular eignet sich hervorragend für kleinere, dynamische Anwendungen, die mit minimalem Framework-Code auskommen, und ist damit eine ideale Wahl für schnelle Entwicklungszyklen. Dies ist besonders nützlich, wenn es darum geht, Prototypen zu erstellen oder Projekte mit kurzen Entwicklungszeiten umzusetzen. Es ist jedoch auch entscheidend, das richtige Gleichgewicht zwischen Einfachheit und Skalierbarkeit zu finden, wenn die Anforderungen wachsen.

Für größere, unternehmensweite Anwendungen wie LOB-Apps ist es wichtig, ein klares Architekturmodell zu wählen, das sowohl Flexibilität als auch Wartbarkeit gewährleistet. LOB-Anwendungen sind das Rückgrat vieler Unternehmen und bieten eine wertvolle Gelegenheit, verschiedene Funktionen und Technologien zu demonstrieren, ohne sich auf spezielle und komplexe Anforderungen konzentrieren zu müssen, die in größeren, spezialisierten Unternehmensanwendungen auftreten können. Der Prinzip der 80-20-Regel zeigt uns, dass mit einem gut durchdachten Design ein Großteil der Ziele effizient erreicht werden kann, ohne die Komplexität unnötig zu steigern.

Ein wesentlicher Aspekt bei der Entwicklung von Unternehmensanwendungen ist die Wahl des richtigen Architekturansatzes. In diesem Fall wird der Router-First-Ansatz als bewährte Methode hervorgehoben. Dieser Ansatz ermöglicht es, die Anwendung um wiederverwendbare Komponenten zu bauen und gleichzeitig die Navigation effizient zu verwalten. Durch die Einführung von Router-First können verschiedene Datenentitäten und deren Beziehungen in der Anwendung strukturiert und modularisiert werden, was die Skalierbarkeit und Wartbarkeit der Anwendung verbessert.

Ein weiterer wichtiger Punkt ist die Verwendung von Angular Signals und die reaktive Programmierung. Diese Technologien ermöglichen es, Anwendungen zu entwickeln, die schneller und reaktiver auf Benutzerinteraktionen und Datenänderungen reagieren. Durch die Kombination von Angular Signals mit bewährten Praktiken der reaktiven Programmierung können Entwickler Anwendungen bauen, die nicht nur leistungsfähig sind, sondern auch gut strukturiert und einfach zu warten.

Es ist ebenfalls von Bedeutung, dass die Architektur einer LOB-Anwendung nicht nur auf technischen Überlegungen beruht, sondern auch auf einer guten Planung und einem klaren Verständnis der geschäftlichen Anforderungen. Die Erstellung von High-Level-Mockups, bevor mit der Implementierung begonnen wird, ist ein unverzichtbarer Schritt, um die Erwartungen der Stakeholder zu verstehen und sicherzustellen, dass die Anwendung die gewünschten Geschäftsziele erfüllt. Auch wenn sich diese Anforderungen während des Entwicklungsprozesses ändern können, hilft ein klarer Designansatz dabei, den Überblick zu behalten und die richtigen Entscheidungen zu treffen.

Ein weiteres wichtiges Thema ist die Handhabung von Speichermanagement und die Vermeidung von Speicherlecks, die durch ungeschicktes Abonnieren von Observables entstehen können. In Angular ist es wichtig, Subscription-Management-Methoden zu verstehen, um sicherzustellen, dass Ressourcen effizient genutzt werden und keine unnötigen Speicherlecks auftreten. Hierzu gehört auch der Einsatz von Mechanismen wie dem async-Pipe und der gezielten Nutzung von BehaviorSubject oder ReplaySubject, die es ermöglichen, Zustände und Daten effizient und ohne unnötige Wiederholungen zu verwalten.

Die Rolle des technischen Leads oder Architekten ist ebenfalls entscheidend, wenn es darum geht, das Team zu koordinieren und sicherzustellen, dass die gewählte Architektur sowohl technisch machbar als auch wirtschaftlich sinnvoll ist. Der Erfolg eines Projekts hängt zu einem großen Teil von der richtigen Führung und den effizienten Planungsprozessen ab. Eine fundierte Planung mit Tools wie Kanban und GitHub-Projekten sorgt dafür, dass Aufgaben organisiert und Fristen eingehalten werden.

Abschließend lässt sich sagen, dass die Entwicklung einer LOB-Anwendung nicht nur eine technologische Herausforderung darstellt, sondern auch eine organisatorische und geschäftliche. Die Wahl der richtigen Architektur, die Anwendung der richtigen Prinzipien und die Fähigkeit, flexibel auf sich ändernde Anforderungen zu reagieren, sind entscheidend für den Erfolg eines Projekts. Mit der richtigen Planung und den richtigen Tools können Entwickler jedoch sicherstellen, dass ihre Anwendung nicht nur die aktuellen Anforderungen erfüllt, sondern auch für zukünftige Erweiterungen gut gerüstet ist.

Wie man die Architektur von Softwareprojekten optimiert, um Kosten zu sparen und Flexibilität zu erhalten

Die Entwicklung von Software erfordert häufig eine sorgfältige Abwägung zwischen Kosten, Funktionalität und Flexibilität. Während kleine Apps anfänglich mit wenig technischer Schulternlast entwickelt werden und schnell wachsen können, neigen größere Unternehmensanwendungen dazu, mit massiven Überaufwänden zu starten. Letztlich müssen alle Projekte eine kritische Schwelle erreichen, an der ihre ursprüngliche Architektur nicht mehr ausreicht. In solchen Fällen wird eine kostspielige Umstrukturierung erforderlich, um wieder auf Kurs zu kommen. Der Schlüssel zur Vermeidung dieses Szenarios liegt in einer Architektur, die auf Flexibilität ausgelegt ist, um sich ändernden Anforderungen gerecht zu werden.

Ein zentrales Konzept, das im Rahmen der Softwareentwicklung von großen und kleinen Apps zunehmend an Bedeutung gewinnt, ist die „Router-first“-Architektur. Dieser Ansatz wurde erstmals 2018 eingeführt und hat sich als erfolgreich erwiesen, um teure Re-Engineering-Maßnahmen zu vermeiden und den Entwicklungsaufwand optimal zu steuern. Router-first Architektur verfolgt die Strategie, die technische Schulternlast zu minimieren, um sowohl die Flexibilität zu maximieren als auch die Kosteneffizienz zu wahren.

Im Vergleich zu kleinen Apps, die anfangs wenig Infrastruktur benötigen, starten große Unternehmensanwendungen oft mit einer übertriebenen technischen Komplexität, die sich im Laufe der Zeit als ineffizient herausstellen kann. Dies führt zu einer wachsenden Systemkomplexität, die bei ungenügender Planung das ursprüngliche Design unzureichend macht. Daher ist es von entscheidender Bedeutung, dass Unternehmen die Architektur ihrer Apps kontinuierlich anpassen und optimieren, bevor sie an die Grenze ihrer Skalierbarkeit stoßen.

Eine weitere wichtige Erkenntnis ist, dass zwischen kleinen Apps und großen Unternehmensanwendungen auch sogenannte „Line of Business“-Apps (LOB-Apps) existieren. Diese befinden sich irgendwo im mittleren Bereich und entwickeln sich aus kleinen Apps oder verlieren ihre Funktionen im Zuge der Nutzung. LOB-Apps sind oft ein Resultat einer Business-Strategie, bei der eine Anwendung primär für ein einziges Ziel verwendet wird, obwohl sie ursprünglich als umfassendere Lösung konzipiert wurde. Die Herausforderung bei der Entwicklung solcher Apps besteht darin, eine Balance zwischen erforderlicher Funktionalität und einem minimalen, aber skalierbaren Architekturaufwand zu finden.

Die „Router-first“-Architektur hilft dabei, diese Balance zu erreichen, indem sie den Entwicklungsaufwand auf das notwendige Maß beschränkt und dennoch genügend Flexibilität für künftige Anpassungen bietet. Dieser Ansatz basiert auf der Idee, dass die Architektur einer Anwendung so entworfen wird, dass sie von Anfang an eine klare Struktur bietet, die später problemlos erweitert oder geändert werden kann, ohne umfangreiche Überarbeitungen vornehmen zu müssen. Ein wesentlicher Bestandteil der Router-first-Architektur ist die Planung und Umsetzung von „lazy loading“ und einer klar strukturierten Navigation, die es ermöglicht, dass die App auf eine Weise wächst, die sowohl für die Benutzer als auch für das Entwicklerteam überschaubar bleibt.

Der Erfolg einer solchen Architektur hängt jedoch nicht nur von der Technik ab, sondern auch von einer disziplinierten Vorgehensweise im Team. Ein ausgewogenes Verhältnis zwischen den technischen Anforderungen und den Fähigkeiten des Entwicklerteams ist unerlässlich. Insbesondere muss bei der Implementierung eines neuen Architekturmodells darauf geachtet werden, dass alle Teammitglieder auf dem gleichen Stand sind und die langfristigen Auswirkungen der getroffenen Entscheidungen verstehen. Experimentieren und Innovation sind zwar notwendig, jedoch sollte der Entwicklungsprozess immer so gestaltet sein, dass er das Team nicht überfordert und unnötige Risiken vermieden werden.

Um diese Prinzipien umzusetzen, erfordert es eine sorgfältige Planung, die sowohl die kurzfristigen als auch die langfristigen Bedürfnisse berücksichtigt. Die Architektur muss nicht nur die aktuellen Anforderungen erfüllen, sondern auch auf mögliche zukünftige Änderungen und Erweiterungen vorbereitet sein. Eine solche vorausschauende Planung ist besonders wichtig in einer Welt, in der sich Geschäftsanforderungen schnell ändern können und Softwarearchitekturen eine hohe Flexibilität bieten müssen, um mit diesen Veränderungen Schritt zu halten.

Neben der flexiblen Architektur sollte das Entwicklerteam darauf achten, dass der Code so strukturiert ist, dass er die Wiederverwendbarkeit maximiert. Moderne Programmiersprachen und -technologien, wie TypeScript und moderne JavaScript-Features, spielen eine entscheidende Rolle dabei, die Wiederverwendbarkeit von Code zu maximieren und gleichzeitig die Komplexität zu verringern. In der Praxis bedeutet dies, dass Entwickler von Anfang an darauf achten sollten, dass ihre Codebasis modular und gut strukturiert ist, um spätere Anpassungen und Erweiterungen zu erleichtern.

Letztlich ist es die Balance zwischen der Notwendigkeit, die Architektur effizient und anpassbar zu gestalten, und der Disziplin des Entwicklerteams, die den Erfolg eines Softwareprojekts bestimmt. Eine ausgewogene Architektur sollte daher immer darauf abzielen, den langfristigen Wert der Software sicherzustellen, indem sie den Engineering-Aufwand minimiert, gleichzeitig aber genügend Raum für notwendige Anpassungen bietet, ohne die Stabilität der Anwendung zu gefährden.

Wie man benutzerdefinierte Formulare in Angular erstellt und validiert

Im modernen Webentwicklungskontext sind Formulare ein zentrales Element, insbesondere wenn es darum geht, Benutzerinformationen zu sammeln oder zu bearbeiten. In Angular bietet das ReactiveFormsModule eine leistungsstarke Möglichkeit, Formulare zu erstellen und zu validieren. Bei der Arbeit mit komplexen Formstrukturen und dynamischen Daten ist es jedoch entscheidend, die besten Praktiken für eine reibungslose Benutzererfahrung (UX) und eine korrekte Datenverarbeitung zu kennen. Diese Einführung beschäftigt sich mit den Prinzipien und Techniken zur Erstellung benutzerdefinierter Formulare, ihrer Validierung und Optimierung der Benutzererfahrung.

Zunächst ist es wichtig zu verstehen, dass ein Formular in Angular aus mehreren Bestandteilen besteht. FormControls, die die einzelnen Eingabefelder repräsentieren, bilden die Grundlage des Formulars. Diese FormControls können in FormGroups gruppiert werden, die verwandte FormControls enthalten, wie etwa die verschiedenen Teile eines Namens oder eine Adresse. Innerhalb dieser FormGroups können sogar wieder FormGroups oder FormArrays verwendet werden, um komplexere und dynamische Datenstrukturen zu unterstützen.

Ein Beispiel für den Aufbau eines Formulars könnte folgendermaßen aussehen: In einer Benutzeroberfläche, in der ein Benutzer seine E-Mail-Adresse, seinen Namen, Geburtsdatum und Adresse eingeben muss, könnte der Code eine FormGroup mit FormControl für jedes Eingabefeld beinhalten. Die E-Mail-Adresse könnte mit einer Validierung versehen werden, die sicherstellt, dass der Benutzer eine gültige Adresse eingibt. Der Name könnte wiederum in einem eigenen FormGroup enthalten sein, das die Felder für Vorname, Mittelname und Nachname umfasst. Dies ist besonders wichtig, um die Struktur der Daten korrekt zu halten und sicherzustellen, dass die eingegebenen Werte später problemlos verarbeitet werden können.

Ein gängiges Problem bei der Arbeit mit Formulardaten ist das asynchrone Laden von Informationen, insbesondere wenn diese aus einer API abgerufen werden müssen. In solchen Fällen kann es zu einer unangenehmen Benutzererfahrung kommen, wenn das Formular erst dann korrekt angezeigt wird, wenn alle Daten vollständig geladen sind. Ein Ansatz zur Verbesserung dieser Situation ist das Hinzufügen eines Ladeindikators, der während der Datenabfrage angezeigt wird, und das Deaktivieren der Formularfelder, bis die Informationen vollständig verfügbar sind. Dies verhindert, dass der Benutzer mit unvollständigen oder falschen Daten interagiert.

Ein weiteres häufiges Problem ist die wiederholte Verwendung von Formularlogik in verschiedenen Komponenten. Besonders in größeren Anwendungen, in denen viele Komponenten Formulare enthalten, ist es entscheidend, eine Lösung zu finden, die sowohl wiederverwendbar als auch wartbar ist. Eine Möglichkeit, dieses Problem zu lösen, ist der Einsatz eines globalen Ladeindikators. Mithilfe eines HttpInterceptor können API-Anfragen abgefangen und deren Abschluss überwacht werden. Dadurch können wir eine globale Benachrichtigung anzeigen, die dem Benutzer signalisiert, dass die Daten abgerufen werden, ohne dass jede einzelne Komponente ihre eigene Ladeanzeige implementieren muss. In komplexen Anwendungen, bei denen Formulardaten oft in verschiedenen Komponenten bearbeitet werden, sollte man jedoch auch die Möglichkeit in Betracht ziehen, einen eigenen Ladeindikator auf der Komponentenseite zu implementieren.

Die Validierung von Formulardaten ist ein weiterer kritischer Aspekt. Angular bietet eingebaute Validatoren, wie Validators.required oder Validators.email, die sicherstellen, dass die Benutzereingaben den erforderlichen Formatanforderungen entsprechen. Eine erweiterte Form von Validierung ist das Erstellen benutzerdefinierter Validatoren, die komplexere Logik umsetzen können, wie etwa die Überprüfung eines US-amerikanischen Postleitzahlenformats oder das Sicherstellen, dass ein Benutzername eine bestimmte Länge hat. Solche benutzerdefinierten Validierungen können sehr nützlich sein, um sicherzustellen, dass die Formulareingaben korrekt sind, bevor sie an einen Server gesendet werden.

Die Implementierung von Formularen kann auch durch den Einsatz von Angular Material-Komponenten, wie dem MatStepper, optimiert werden. Ein Stepper unterteilt ein Formular in mehrere Schritte, die der Benutzer nacheinander ausfüllt. Dies reduziert die kognitive Belastung, indem die Eingabefelder in überschaubare Abschnitte unterteilt werden. Ein Stepper unterstützt die Benutzer bei der Navigation durch das Formular, stellt jedoch auch sicher, dass jeder Schritt abgeschlossen und validiert wird, bevor der Benutzer zum nächsten übergeht. Darüber hinaus sorgt Angular Material für eine responsive Gestaltung, sodass das Formular auf verschiedenen Bildschirmgrößen und Geräten gut funktioniert.

In Bezug auf die Implementierung von FormArrays, also Feldern mit dynamischen Einträgen, kann es erforderlich sein, dass der Benutzer mehrere Datensätze eingibt, z. B. mehrere E-Mail-Adressen oder Telefonnummern. Mit FormArrays können wir diese Anforderungen flexibel umsetzen, indem wir Felder dynamisch hinzufügen oder entfernen, ohne die Struktur des gesamten Formulars neu zu definieren. Dies ermöglicht eine äußerst anpassbare und benutzerfreundliche Lösung.

Ein weiterer Aspekt ist die Berechnung von Eigenschaften innerhalb des Formulars. In einigen Fällen möchten wir, dass bestimmte Felder automatisch basierend auf den Eingaben des Benutzers berechnet werden. Dies könnte beispielsweise das Geburtsdatum sein, aus dem automatisch das Alter des Benutzers abgeleitet wird. Solche Berechnungen können direkt im Formular durchgeführt werden, was die Interaktivität und Benutzerfreundlichkeit weiter verbessert.

Zusätzlich zur Benutzererfahrung ist die Effizienz der Datenspeicherung und -übertragung ein wichtiger Punkt. Beim Absenden eines Formulars ist es notwendig, die Daten in einem geeigneten Format zu serialisieren. In Angular wird dies in der Regel durch ein Formularmodell erreicht, das die benutzerdefinierten FormGroups und FormControls umfasst. Bei komplexen Formularen ist es ratsam, die Daten regelmäßig zu speichern oder zwischenspeichern, um den Verlust von Benutzereingaben zu vermeiden.

Die Herausforderungen, die bei der Entwicklung von Formularen auftreten, sind vielfältig und erfordern eine sorgfältige Planung und Umsetzung. Besonders bei größeren Anwendungen mit einer Vielzahl an Formularen und unterschiedlichen Anforderungen müssen Lösungen gefunden werden, die sowohl die Wiederverwendbarkeit von Code maximieren als auch eine exzellente Benutzererfahrung bieten. Das richtige Zusammenspiel von Angular-Formularen, benutzerdefinierten Validierungen, dynamischen FormArrays und der Implementierung von Angular Material-UI-Komponenten ermöglicht es, Formulare zu erstellen, die sowohl funktional als auch benutzerfreundlich sind.

Wie verwaltet man den Zustand in Angular mit NgRx und anderen State-Management-Lösungen?

Im Angular-Ökosystem ist die Verwaltung des Zustands eine zentrale Herausforderung für die Entwicklung großer und wartbarer Anwendungen. NgRx, eine weit verbreitete Bibliothek für die Zustandsverwaltung, bietet eine solide Grundlage für die Verwaltung von globalem Zustand und die Handhabung komplexer Datenflüsse. Doch es gibt auch andere Ansätze, die weniger Boilerplate-Code benötigen oder sich auf spezifische Anwendungsszenarien fokussieren. In dieser Diskussion werfen wir einen Blick auf NgRx und einige verwandte Technologien, die als Alternativen oder Erweiterungen dienen.

Der Einsatz von NgRx als State-Management-Lösung ist vor allem dann sinnvoll, wenn Anwendungen wachsen und der globale Zustand zentralisiert und eindeutig verwaltet werden muss. Die NgRx-Bibliothek folgt dabei der Flux-Architektur, die einen unidirektionalen Datenfluss garantiert und eine klare Trennung zwischen Zustand und Logik aufrechterhält. Dies ermöglicht es, den Zustand der Anwendung in einer Weise zu modellieren, die leicht nachvollziehbar und vorhersehbar ist.

Ein wesentlicher Bestandteil von NgRx ist der Store, der als zentrales Speicherobjekt für den gesamten Zustand der Anwendung dient. Darüber hinaus bieten NgRx-Effects die Möglichkeit, Nebenwirkungen wie HTTP-Anfragen oder das Abrufen von Daten asynchron zu handhaben. Dies unterstützt eine klare Trennung von Logik und ermöglicht es, reaktive Programme zu erstellen, die sich gut in Angular integrieren. Während NgRx eine mächtige Lösung darstellt, kann die Menge an Boilerplate-Code, die für einfache Operationen erforderlich ist, als unnötig komplex wahrgenommen werden.

Ein Ansatz, um diesen Overhead zu reduzieren, ist die Verwendung von NgRx/Data. Diese Erweiterung vereinfacht die Verwaltung von Entitäten, indem sie standardisierte CRUD-Operationen (Create, Retrieve, Update, Delete) abstrahiert. Damit können Entwickler die Vorteile von NgRx nutzen, ohne sich um die Details der Store- und Effekt-Implementierung kümmern zu müssen. Trotz dieser Vereinfachung wurde NgRx/Data ab Version 17 jedoch in den Wartungsmodus versetzt, und es wird nicht mehr für neue Projekte empfohlen. Diese Entscheidung basiert auf der Tatsache, dass NgRx/Data nicht alle erforderlichen Funktionen für die Verwaltung von Entitäten wie Tiefenklonung, serverseitige Abfragen oder komplexe Beziehungen bietet.

Ein weiteres interessantes Konzept innerhalb des NgRx-Ökosystems ist NgRx/ComponentStore, das speziell für die Verwaltung von lokalem Zustand innerhalb von Angular-Komponenten entwickelt wurde. ComponentStore ist eine leichtere Lösung, die sich gut für kleinere, isolierte Anwendungsbereiche eignet. Es ermöglicht eine reaktive Zustandsverwaltung ohne den globalen Store, was den Code einfacher und wartungsfreundlicher macht. ComponentStore eignet sich besonders für komplexe Komponenten, die viele lokale Zustände und Interaktionen erfordern, da es die Trennung von Zustandslogik und UI fördert.

ComponentStore stellt sicher, dass der Zustand der Komponente unabhängig und wiederverwendbar bleibt. Diese Lösung bietet sich als Alternative zu dem traditionellen Ansatz der „Service mit Subject“-Muster an, was einen klaren Vorteil in der Testbarkeit und Wartbarkeit bringt. Allerdings ist ComponentStore nicht für große, komplexe Anwendungen gedacht, bei denen der globale Zustand über mehrere Komponenten hinweg geteilt werden muss.

Eine noch neuere Entwicklung in der Angular-Welt ist NgRx/Signals, das die Nutzung von Angular Signals integriert. Diese Technologie stellt eine einfache, deklarative API zur Verfügung und ist für die reaktive Zustandsverwaltung in Angular-Anwendungen optimiert. Der Vorteil von NgRx/Signals liegt in seiner minimalistischen Architektur, die den Code vereinfacht und gleichzeitig die Performance optimiert. Dies führt zu leichter verständlichem und wartbarem Code, der sich gut für die Entwicklung flexibler und skalierbarer Anwendungen eignet. Die Hauptunterscheidung zu anderen Lösungen wie NgRx/Store oder ComponentStore liegt in der Nutzung von Signals anstelle von Observables, was eine einfachere und weniger fehleranfällige Implementierung ermöglicht.

Die Entscheidung, welches State-Management-Modell für eine bestimmte Anwendung am besten geeignet ist, hängt von vielen Faktoren ab, einschließlich der Größe der Anwendung, der Komplexität des Zustands und der benötigten Skalierbarkeit. Während NgRx und NgRx/Store eine robuste Lösung für größere Anwendungen bieten, können NgRx/Data, ComponentStore und NgRx/Signals für kleinere, weniger komplexe Projekte von Vorteil sein.

Es ist wichtig, dass Entwickler den richtigen Ansatz für den jeweiligen Anwendungsfall wählen, da jede dieser Lösungen ihre eigenen Stärken und Schwächen hat. Wer zum Beispiel viele CRUD-Operationen benötigt, könnte von der Verwendung von NgRx/Data profitieren, während für einfache, isolierte Komponenten NgRx/ComponentStore oder Signals möglicherweise besser geeignet sind.

Für die langfristige Wartbarkeit ist es jedoch unerlässlich, sich mit den internen Mechanismen von NgRx und den zugrunde liegenden Prinzipien des reaktiven Programmierens vertraut zu machen. Auch wenn eine vereinfachte Lösung wie NgRx/Data oder NgRx/ComponentStore zu Beginn den Entwicklungsaufwand reduziert, könnte der Entwickler später auf Herausforderungen stoßen, wenn tiefere Anpassungen erforderlich sind.

Die Wahl des richtigen State-Management-Ansatzes sollte sich daher immer an den langfristigen Zielen des Projekts orientieren. Entwickler sollten sich darüber im Klaren sein, dass die Entscheidung für eine bestimmte Lösung Auswirkungen auf die Wartbarkeit und Skalierbarkeit ihrer Anwendung haben kann.