Wenn das Frontend gegen sein Framework arbeitet
Warum imperatives OOP-Denken im Backend oft trägt — im modernen Frontend aber gegen Angular, React und Vue arbeitet.

Das Projekt nutzte Angular.
Zumindest stand Angular in der package.json.
Auf den ersten Blick war alles da: Komponenten, Templates, Services, Routing, Formulare, HTTP-Aufrufe. Ein modernes Frontend also. Technisch gesehen.
Architektonisch sah es anders aus.
Das Routing wurde nicht wirklich über den Angular Router gedacht, sondern durch ein eigenes Routing-System ergänzt oder ersetzt. Validation wurde nicht über Forms, Validatoren oder ein klares ViewState-Modell modelliert, sondern über eigene Validierungslogik. Change Detection wurde nicht verstanden, sondern mit eigenen Mechanismen zur UI-Synchronisation umgangen. State Management wurde nicht als Zustand, Ereignis und Ableitung gedacht, sondern über eigene Cache-Klassen gebaut.
Das klingt hart. Ist aber nicht als Vorwurf gemeint.
Jede einzelne Entscheidung war vermutlich lokal erklärbar. Das Team wollte Probleme lösen. Das Team wollte Kontrolle. Das Team wollte liefern. Niemand wacht morgens auf und denkt: „Heute baue ich ein Gegenframework in Angular.“
Genau deshalb ist das Muster gefährlich.
Es entsteht nicht aus Dummheit. Es entsteht aus Kompetenz in einem anderen Kontext.
Viele sehr gute Entwickler wurden über Jahre auf objektorientiertes Denken, Services, Methoden, Transaktionen und lineare Abläufe trainiert. Durch Studium. Durch klassische Softwaretechnik. Durch Backend-Projekte. Durch Enterprise-Systeme. Durch Frameworks, in denen ein Request beginnt, verarbeitet wird und endet.
Das ist nicht falsch.
Es hat nur einen anderen Heimathafen.
Warum Backend-Denken hier naheliegt
Abschnitt betitelt „Warum Backend-Denken hier naheliegt“Ein typischer Backend-Ablauf sieht oft ungefähr so aus:
Request kommt rein. Validierung läuft. Daten werden geladen. Regeln werden geprüft. Daten werden gespeichert. Response geht raus.
Das passt gut zu imperativem Denken.
Die zentrale Frage lautet:
Was passiert als Nächstes?
Es passt auch gut zu klassischem OOP-Denken.
Die zentrale Frage lautet:
Welches Objekt ist zuständig? Welche Methode rufe ich auf?
Das ist in vielen Backend-Kontexten sinnvoll. Ein Use Case orchestriert einen Ablauf. Ein Service kapselt fachliche Logik. Ein Repository lädt Daten. Eine Transaktion begrenzt den Vorgang. Am Ende gibt es ein Ergebnis.
Der Vorgang hat einen Anfang. Er hat ein Ende. Dazwischen gibt es eine nachvollziehbare Reihenfolge.
Frontend fühlt sich zunächst ähnlich an. Ein Nutzer klickt. Eine Methode wird ausgeführt. Ein Service wird aufgerufen. Daten kommen zurück. Die UI wird aktualisiert.
Also überträgt man das bekannte Modell.
Das Problem ist: Eine UI ist kein einzelner Request.
Das Backend verarbeitet oft einen Vorgang. Das Frontend hält eine laufende Situation konsistent.
Und genau an dieser Stelle kippt das Denken.
Was imperativ bedeutet
Abschnitt betitelt „Was imperativ bedeutet“Imperativ bedeutet: Code beschreibt, welche Schritte nacheinander ausgeführt werden sollen.
Zum Beispiel:
async save(): Promise<void> { this.loading = true; this.error = null;
try { const result = await this.api.save(this.formValue); this.items = await this.api.loadItems(); this.toast.success('Gespeichert'); this.router.navigate(['/items', result.id]); } catch (error) { this.error = 'Speichern fehlgeschlagen'; this.toast.error('Speichern fehlgeschlagen'); } finally { this.loading = false; }}Das ist verständlich.
Es ist linear. Es sieht kontrollierbar aus. Es funktioniert im Happy Path. Es ist leicht zu debuggen, solange wenig gleichzeitig passiert.
Click → Save → Success → Toast → Navigate.
Das fühlt sich vertraut an. Gerade für Entwickler, die aus Backend, OOP oder klassischer Anwendungsentwicklung kommen.
Und um das klar zu sagen: Imperativer Code ist nicht grundsätzlich schlecht. Natürlich gibt es im Frontend imperative Stellen. Ein Button-Klick ist ein Ereignis. Eine Navigation ist ein Effekt. Ein HTTP-Request wird ausgelöst. Ein Dialog wird geöffnet.
Das Problem beginnt nicht dort, wo einmal imperativer Code steht.
Das Problem beginnt dort, wo die gesamte UI als manuell gesteuerte Schrittfolge gebaut wird.
Dann wird aus jedem Zustand ein Flag. Aus jedem Sonderfall eine Reihenfolge. Aus jeder UI-Reaktion ein Methodenaufruf. Aus jeder Inkonsistenz ein weiterer Helper.
Und irgendwann besteht der Screen nicht mehr aus einem Modell, sondern aus Ablaufkoordination.
Was klassisches OOP bedeutet
Abschnitt betitelt „Was klassisches OOP bedeutet“OOP denkt häufig in Objekten, Zuständigkeiten und Methoden.
Ein Objekt kapselt Daten und Verhalten. Ein Service führt eine Aktion aus. Ein Controller orchestriert einen Ablauf. Ein Use Case beschreibt einen Vorgang.
In Backend-Systemen kann das sehr hilfreich sein. Viele Prozesse sind dort begrenzt. Sie laufen innerhalb eines Requests, einer Message, eines Jobs oder einer Transaktion. Man kann Verantwortung schneiden, Abhängigkeiten injizieren und Verhalten kapseln.
Im Frontend rutscht dieses Denken aber schnell an eine ungünstige Stelle.
Die Komponente wird dann zum kleinen Controller. Sie lädt Daten. Sie hält Cache-Zustände. Sie validiert. Sie entscheidet über Sichtbarkeit. Sie synchronisiert Template und Modell. Sie reagiert auf Routenwechsel. Sie verwaltet Ladezustände. Sie zeigt Toasts. Sie navigiert. Sie behandelt Fehler. Sie ruft Reloads auf.
Irgendwann ist sie nicht mehr nur Komponente.
Sie ist Controller, Prozessmanager, Cache-Verwalter, Validator und Render-Koordinator gleichzeitig.
Ein Angular Component ist kein kleiner Backend-Controller mit Template.
Das gilt nicht nur für Angular. Auch React-Komponenten sind keine kleinen Controller mit JSX. Vue-Komponenten sind keine Ablaufskripte mit Template-Syntax.
Moderne Frontend-Komponenten sind Teil eines reaktiven Laufzeitmodells.
Und dieses Modell muss man ernst nehmen.
Was reaktiv bedeutet
Abschnitt betitelt „Was reaktiv bedeutet“Reaktiv klingt oft größer, als es sein müsste.
Man muss daraus keine akademische Grundsatzdebatte machen. Für den Alltag reicht zunächst diese Idee:
Reaktiv bedeutet, dass nicht jeder Schritt manuell gesteuert wird. Stattdessen werden Zustände, Ereignisse und Ableitungen modelliert.
Nicht:
Zeige jetzt den Spinner.
Sondern:
Der Status ist
loading, also zeigt die UI den Spinner.
Nicht:
Verstecke die Fehlermeldung, rendere die Liste neu und prüfe danach den Empty State.
Sondern:
Aus State und ViewModel ergibt sich, ob Fehler, Liste, Empty State oder Ladezustand sichtbar sind.
Nicht:
Wenn das passiert, setze dieses Flag, lösche jenes Array, rufe Reload auf und triggert danach die UI.
Sondern:
Ein Intent verändert Zustand. Aus diesem Zustand ergibt sich die nächste Projektion.
Reaktiv fragt nicht zuerst:
Was muss ich jetzt ausführen?
Reaktiv fragt:
Welche Situation liegt vor — und was ergibt sich daraus?
Oder kürzer:
Imperativ fragt: Was passiert als Nächstes? Reaktiv fragt: Was ergibt sich aus dem Zustand?
Das ist ein massiver Denkwechsel.
Nicht, weil reaktiv „moderner“ klingt. Sondern weil eine UI dauerhaft lebt. Sie ist offen, während Nutzer interagieren, Requests laufen, Routen wechseln, Komponenten verschwinden, Daten nachgeladen werden und Validierung sich während der Eingabe verändert.
Eine UI ist weniger ein Ablauf.
Sie ist eine laufende Projektion.
UI ist keine Schrittfolge. UI ist eine Projektion.
Imperativ, OOP, reaktiv
Abschnitt betitelt „Imperativ, OOP, reaktiv“
Man kann den Unterschied grob so schneiden:
| Denkmodell | Zentrale Idee | Typische Frage | Stärke | Gefahr im Frontend |
|---|---|---|---|---|
| Imperativ | Ablauf, Reihenfolge, Methodenaufruf | Was passiert als Nächstes? | Verständliche Schrittfolgen | Manuelle UI-Synchronisation |
| OOP | Objekt, Methode, Zuständigkeit, Kapselung | Wer macht es? | Verantwortlichkeiten und Kapselung | Komponenten werden Controller |
| Reaktiv | Zustand, Ereignis, Ableitung, Projektion | Was ergibt sich? | Konsistente UI aus State | Anfangs ungewohntes Denken |
Keines dieser Modelle ist per se falsch.
Die Frage ist: In welchem Laufzeitmodell bewege ich mich?
Im Backend ist ein linearer Ablauf oft natürlich. Im Frontend ist er oft nur der Happy Path. Sobald echte UI-Komplexität entsteht, überlagern sich Zustände.
Der Nutzer klickt mehrfach. Requests laufen parallel. Routen wechseln. Komponenten entstehen und verschwinden. Validierung ändert sich während der Eingabe. Berechtigungen wirken. Lade-, Fehler-, Leer- und Erfolgszustände überlagern sich. Browser History und Deep Links existieren. Rendering passiert wiederholt.
Ein moderner Screen ist deshalb weniger ein Ablaufdiagramm.
Er ist eher eine laufende Zustandsmaschine.
Warum es kurzfristig funktioniert
Abschnitt betitelt „Warum es kurzfristig funktioniert“Imperativer Frontend-Code funktioniert oft zunächst erstaunlich gut.
Der Happy Path ist linear:
Click → Save → Success → Toast → Navigate.
Das ist schnell geschrieben. Es ist nachvollziehbar. Es passt zu erfahrenen OOP-Reflexen. Es gibt ein Gefühl von Kontrolle.
Gerade in frühen Projektphasen wirkt das produktiv. Man sieht Ergebnisse. Features entstehen. Die UI reagiert. Kunden können klicken.
Und wenn etwas nicht passt, fügt man noch ein Flag hinzu.
isLoading.
isSaving.
hasError.
showEmptyState.
isInitialized.
reloadRequired.
formWasTouched.
manualRefreshNeeded.
Auch das funktioniert erst einmal.
Bis mehrere Dinge gleichzeitig passieren.
Dann beginnt die eigentliche Komplexität: Welche Flags schließen sich gegenseitig aus? Welcher Request darf welchen Zustand überschreiben? Was passiert, wenn der Nutzer während des Speicherns die Route wechselt? Wer setzt den Fehler zurück? Wann ist ein Cache veraltet? Warum bleibt der Spinner stehen? Warum wird die Liste nicht aktualisiert? Warum erscheint ein Toast zweimal?
An diesem Punkt wird aus Kontrolle Koordination.
Und Koordination ist teuer.
Warum es langfristig gegen das Framework arbeitet
Abschnitt betitelt „Warum es langfristig gegen das Framework arbeitet“Angular, React und Vue unterscheiden sich stark in APIs, Philosophie und Ökosystem.
Aber sie teilen eine Grundidee:
Rendering entsteht aus Zustand.
React denkt UI über State und Props. Wenn sich State ändert, ergibt sich daraus ein neuer Render. Vue arbeitet über reaktive Daten, computed values und Template Bindings. Angular bewegt sich immer stärker in Richtung Signals, computed values, Template Bindings, Router-State, Forms-State, Resources, Stores und klarer Änderungsmodelle.
Die APIs sind verschieden.
Das Paradigma ist ähnlich:
UI ist eine Projektion von Zustand.
Die Frameworks wollen nicht, dass man den Screen dauerhaft Schritt für Schritt manuell synchronisiert. Sie wollen, dass man Zustände modelliert, Abhängigkeiten ausdrückt und Ableitungen beschreibt.
Wer dagegen alles selbst koordiniert, arbeitet am Framework vorbei.
Das sieht dann oft so aus:
Der Router wird nicht als Navigationsmodell verstanden, sondern als störender Mechanismus. Forms werden nicht als Zustandsmodell verstanden, sondern als Eingabefelder mit eigenen Error-Maps. Change Detection wird nicht als Rendering-Modell verstanden, sondern als etwas, das man manuell „anstupsen“ muss. State Management wird nicht als Projektion von Ereignissen und Zustand verstanden, sondern als Sammlung globaler Cache-Klassen.
Dann nutzt man Angular, React oder Vue nur noch als Render-Schicht.
Das eigentliche Laufzeitmodell liegt im eigenen Code.
Das Gegenframework im Framework
Abschnitt betitelt „Das Gegenframework im Framework“
Das Gefährliche ist selten der erste Helper.
Ein Helper ist harmlos. Ein Workaround ist erklärbar. Eine eigene kleine Abstraktion ist oft sinnvoll.
Aber Workarounds haben Karrieren.
Heute löst man ein lokales Problem. Morgen wird daraus ein internes Pattern. Übermorgen hängt ein zweites Team daran. Dann entstehen Konventionen. Dann braucht es Dokumentation. Dann kennt nur noch eine Person die Sonderfälle. Dann wird das Framework-Update schwierig, weil nicht mehr klar ist, welche Verantwortung beim Framework liegt und welche Verantwortung die Eigenlösung übernommen hat.
Wenn der Framework-Router durch einen eigenen Router ersetzt wird, Forms und Validation durch eigene Validierung, Change Detection durch eigene Render-Synchronisation und State Management durch Cache-Klassen, dann nutzt man Angular nicht mehr als Architekturmodell.
Dann ist Angular nur noch die Render-Schicht eines selbstgebauten Frameworks.
Angular war nicht das Problem. Das Problem war der Code, der Angular daran gehindert hat, Angular zu sein.
Das ist der Kern.
Nicht jedes Framework-Konzept ist perfekt. Nicht jede API ist schön. Nicht jede Empfehlung passt zu jedem Projekt. Aber wenn man zentrale Konzepte ersetzt, übernimmt man ihre Verantwortung.
Und diese Verantwortung ist größer, als sie am Anfang aussieht.
Eigener Router
Abschnitt betitelt „Eigener Router“Routing ist nicht nur die Frage:
Welche Seite ist sichtbar?
Routing umfasst Deep Links, Browser History, Guards, Lazy Loading, Redirects, Parameter, Reload-Verhalten, Back-Button, Navigation State, Fehlerfälle und häufig auch Berechtigungen.
Ein eigener Router übernimmt diese Verantwortung oft nur teilweise. Für den ersten Klick reicht das. Für den Happy Path auch. Aber spätestens bei Reload, Browser History, verschachtelten Routen, Guards oder Deep Links merkt man, dass Routing ein Laufzeitmodell ist.
Ein eigener Router ist selten nur ein Router. Er ist der Beginn eines eigenen Laufzeitmodells.
Manchmal gibt es gute Gründe für Routing-Abstraktionen. Zum Beispiel, um fachliche Navigation zu kapseln oder URLs stabil zu halten. Aber diese Abstraktion sollte den Router respektieren, nicht ersetzen.
Eigene Validation
Abschnitt betitelt „Eigene Validation“Validation ist nicht nur:
Feld leer oder nicht?
Validation verbindet User Input, Dirty- und Touched-Zustände, Submit-Fähigkeit, Backend-Fehler, Übersetzungen, Accessibility und Anzeige.
Sobald eigene Validierungslogik neben dem Form-State entsteht, droht doppelte Wahrheit.
Das Form sagt: gültig. Die Error-Map sagt: ungültig. Das Template zeigt: vielleicht. Der Submit-Button entscheidet: nach eigener Logik. Das Backend antwortet: nochmal anders.
Dann beginnt Synchronisation.
Und Synchronisation ist meistens ein Hinweis darauf, dass das Modell falsch geschnitten ist.
Validation gehört nicht irgendwo in eine lose Helper-Klasse, die zufällig Strings auf Felder mappt. Sie braucht ein bewusstes Modell: Was kommt aus dem User Input? Was kommt vom Backend? Was ist Anzeige? Was ist fachliche Regel? Was ist technisches Format?
Erst dann wird Validation testbar und verständlich.
Eigene Change Detection
Abschnitt betitelt „Eigene Change Detection“Eigene Change Detection ist ein besonders starkes Warnsignal.
Natürlich gibt es Spezialfälle. Performance-Optimierungen. Zonenlose Anwendungen. Manuelle Grenzen. Große Listen. Externe APIs.
Aber wenn im normalen Feature-Alltag häufig manuell dafür gesorgt werden muss, dass der Screen „endlich aktualisiert“, ist meist nicht das Rendering das eigentliche Problem.
Oft ist der Zustand falsch modelliert.
Oder er wird am Framework vorbei verändert.
Oder es gibt mehrere Wahrheiten.
Oder Seiteneffekte passieren an Stellen, an denen eigentlich Ableitungen stehen sollten.
Eigene Change Detection ist selten ein Performance-Feature. Sie ist oft ein Architektur-Symptom.
Man kann Rendering optimieren. Man kann Change Detection verstehen und bewusst steuern. Aber man sollte sie nicht als Pflaster für ein unklares Zustandsmodell verwenden.
Eigene Cache-Klassen
Abschnitt betitelt „Eigene Cache-Klassen“Viele Projekte sagen Cache, meinen aber State Management.
Eine Cache-Klasse beginnt harmlos:
private items = new Map<string, Item>();Dann kommt Auswahlzustand dazu. Dann Ladezustand. Dann Fehlerzustand. Dann Invalidierung. Dann Reload. Dann Events. Dann Seiteneffekte. Dann globale Mutable State.
Irgendwann ist die Klasse Store, Repository, Event Bus, Cache und Prozessmanager gleichzeitig.
Und niemand nennt sie so.
Das ist gefährlich, weil ein echter Cache ein klares Invalidierungsmodell braucht. Wann sind Daten gültig? Wer darf sie überschreiben? Was passiert bei parallelen Requests? Was passiert bei Logout? Was passiert bei Mandantenwechsel? Was passiert nach Mutation? Was passiert bei Fehlern?
Ohne diese Antworten ist der Cache kein Cache.
Ein Cache ohne klares Invalidierungsmodell ist kein Cache. Er ist Hoffnung mit Map-Interface.
Auch hier gilt: Eigene Abstraktionen können sinnvoll sein. Aber wenn sie State Management ersetzen, sollten sie auch wie State Management entworfen, getestet und betrieben werden.
Migration als Wahrheitsmoment
Abschnitt betitelt „Migration als Wahrheitsmoment“Der Preis solcher Ersatzsysteme zeigt sich selten beim ersten Feature.
Er zeigt sich später.
Bei Major Upgrades. Bei neuen Framework-Paradigmen. Bei neuen Teammitgliedern. Bei Tests. Bei Refactorings. Bei Security-Anforderungen. Bei Performance-Problemen. Bei Migrationen.
In einer konkreten Projektdiagnose hing ein Projekt 2026 noch auf Angular 17. Eine Analyse ergab: Mit hohem Kraftaufwand, grob 60+ Punkten, wäre vermutlich noch ein Upgrade auf Angular 19 möglich gewesen. Danach wäre wahrscheinlich Schluss gewesen, weil die Eigenlösungen nicht mehr zum Modernisierungskurs des Frameworks passten.
Das ist keine allgemeine Regel. Das ist eine Projektdiagnose.
Aber sie zeigt ein Muster.
Solange das Framework nur als Render-Schicht genutzt wird, verliert man den Anschluss an seine Weiterentwicklung. Neue APIs helfen kaum, wenn das eigene Laufzeitmodell quer dazu liegt. Signals helfen wenig, wenn der eigentliche State in mutable Cache-Klassen steckt. Bessere Forms helfen wenig, wenn Validation komplett daneben gebaut wurde. Router-Verbesserungen helfen wenig, wenn Navigation im eigenen System stattfindet.
Das teuerste an Gegenframeworks ist nicht ihre Implementierung. Es ist ihre Migration.
Lernkurve und Verantwortung der Organisation
Abschnitt betitelt „Lernkurve und Verantwortung der Organisation“Reaktives Denken lernt man nicht in einem Sprint.
Das ist mir wichtig.
Wer jahrelang auf OOP, Services, Methoden, Kontrollfluss und Transaktionen trainiert wurde, wechselt nicht einfach durch ein Framework-Tutorial das Denkmodell. Natürlich kann man eine Signal-API verwenden. Natürlich kann man ein Observable subscriben. Natürlich kann man ein React Hook schreiben.
Aber das bedeutet noch nicht, dass man reaktiv denkt.
Reaktives Denken beginnt erst dort, wo man Zustände, Ereignisse und Ableitungen als Architekturmodell begreift. Wo man nicht mehr zuerst fragt: „Welche Methode rufe ich jetzt auf?“, sondern: „Welche Situation modellieren wir hier eigentlich?“
Aus praktischer Erfahrung dauert es begleitet oft etwa sechs Monate, bis Entwickler anfangen, diese Denkmuster wirklich zu verstehen und nicht nur APIs mechanisch zu verwenden.
Das ist keine Schwäche.
Das ist Lernen.
Viele Organisationen geben diese Zeit aber nicht. Teams sollen moderne Frontends bauen, bekommen aber keine Zeit, das Paradigma zu lernen. Es gibt ein neues Framework, aber kein neues Architekturverständnis. Es gibt Tickets, Deadlines und Lieferdruck. Also greifen Entwickler auf das zurück, was sie beherrschen.
Dann entstehen Workarounds. Dann werden Workarounds Patterns. Dann werden Patterns Architektur. Dann blockiert Architektur das Produkt.
Das ist selten individuelles Versagen.
Es ist oft ein Organisationsproblem.
Wenn Unternehmen moderne Frontends wollen, müssen sie den Paradigmenwechsel ernst nehmen. Nicht als Luxus. Nicht als Schulung für „Frontend-Spielkram“. Sondern als architektonische Grundlage.
Nicht jede eigene Abstraktion ist falsch
Abschnitt betitelt „Nicht jede eigene Abstraktion ist falsch“
Natürlich ist nicht jede eigene Abstraktion falsch.
Im Gegenteil: Gute Architektur braucht Abstraktionen.
Eigene Abstraktionen sind sinnvoll, wenn sie Fachlichkeit schützen, externe Systeme kapseln oder wiederkehrende Use Cases ausdrücken.
Eine gute Abstraktion schützt fachliche Sprache. Sie kapselt Infrastruktur. Sie respektiert das Framework-Paradigma. Sie reduziert Kopplung. Sie macht Verhalten testbarer.
Problematisch wird es, wenn eigene Abstraktionen Framework-Kernkonzepte ersetzen, ohne deren volle Verantwortung zu übernehmen.
Gefährlich sind Abstraktionen, die Routing ersetzen. Validation ersetzen. Change Detection ersetzen. Das State-Modell ersetzen. Doppelte Wahrheit erzeugen. Insiderwissen brauchen. Upgrades blockieren.
Die entscheidende Frage lautet nicht:
Darf ich eine eigene Abstraktion bauen?
Natürlich darf man das.
Die bessere Frage lautet:
Ergänzt diese Abstraktion das Framework — oder ersetzt sie heimlich sein Laufzeitmodell?
Das ist der Unterschied.
Eine Facade über einem Store kann sinnvoll sein. Ein Mapper in ein ViewModel kann sehr sinnvoll sein. Eine ACL gegen fremde API-Modelle ist oft notwendig. Eine fachliche Navigation-Abstraktion kann helfen. Ein klarer Application-Service kann Use Cases ausdrücken.
Aber ein eigener Router, eigene Validation, eigene Change Detection und globale Cache-Klassen sind keine kleinen Hilfen mehr. Sie sind Architekturentscheidungen.
Dann sollte man sie auch so behandeln.
Woran man merkt, dass man gegen das Framework arbeitet
Abschnitt betitelt „Woran man merkt, dass man gegen das Framework arbeitet“Ein Projekt arbeitet nicht deshalb gegen sein Framework, weil irgendwo ein Helper existiert oder eine Methode imperativ aussieht.
Die Warnsignale sind andere:
Wenn Routing nur noch über interne Zustände funktioniert. Wenn Validierung an drei Stellen dieselbe Wahrheit nachbauen muss. Wenn Komponenten regelmäßig manuell Rendering anstoßen. Wenn Cache-Klassen mehr über den Screen wissen als das ViewModel. Wenn ein Framework-Upgrade nicht an APIs scheitert, sondern an Eigenlogik, die Framework-Verantwortung übernommen hat.
Dann ist nicht eine einzelne Zeile Code das Problem.
Dann hat das Projekt begonnen, sein eigenes Laufzeitmodell zu bauen.
Haltet euch bitte an eure Framework-Paradigmen
Abschnitt betitelt „Haltet euch bitte an eure Framework-Paradigmen“Damit sind wir beim eigentlichen Denkzettel:
Haltet euch bitte an eure Framework-Paradigmen.
Nicht aus Dogma.
Nicht, weil Angular, React oder Vue heilig sind. Nicht, weil Framework-Dokumentation immer perfekt ist. Nicht, weil eigene Ideen verboten wären.
Sondern weil Frameworks Laufzeitmodelle sind.
Wer ein Framework auswählt, entscheidet sich nicht nur für Syntax. Nicht nur für Komponenten. Nicht nur für Build-Tools. Man entscheidet sich für ein Denkmodell.
Man kann dieses Denkmodell lernen. Man kann es bewusst verlassen. Man kann an einzelnen Stellen abstrahieren. Man kann es sogar kritisieren.
Aber man sollte es nicht aus Versehen ersetzen.
Wenn ihr Angular, React oder Vue verwendet, dann lasst diese Frameworks auch ihre Arbeit tun.
Modelliert Zustand. Beschreibt Ableitungen. Sendet Intents. Nutzt Routing, Validation und Rendering so, wie das Framework sie denkt. Kapselt Fachlichkeit, aber ersetzt nicht heimlich das Laufzeitmodell.
Alles andere ist am Anfang Kontrolle.
Und am Ende ein eigenes Framework, das niemand bauen wollte.