Frontend-Architekturprinzipien
Einordnung
Moderne Angular-Frontends sind:
- deklarativ
- reaktiv
- datenflussgetrieben
Die folgenden Prinzipien definieren einen normativen Rahmen für wartbare, skalierbare und konsistente UI-Architekturen.
Sie sind bewusst klar formuliert.
1. UI ist Projektion von State
Komponenten projizieren State. Sie orchestrieren ihn nicht.
Implikationen
- Keine imperative Initialisierungslogik
- Kein mehrfacher lokaler Zustand
- ViewModel-Streams oder Signals
- Keine versteckten Datenquellen
2. Ableitung statt Mutation
State wird abgeleitet, nicht manipuliert.
Erlaubt
computedmapcombineLatest- Immutability
Vermeiden
.push()- direkte Objektmutation
- versteckte Setter
3. Keine Spiegelzustände
Es gibt nur eine Quelle der Wahrheit.
Nicht:
users$: Observable<User[]>;
users: User[];
Sondern:
- Stream bleibt Stream
- Signal bleibt Signal
4. Lifecycle ist Infrastruktur, nicht Geschäftslogik
Lifecycle-Hooks enthalten keine Orchestrierung.
Erlaubt:
- minimale Initialisierung
- Effekt-Registrierung
Nicht erlaubt:
- komplexe Datenlade-Logik
- manuelle Subscription-Verwaltung
- Geschäftslogik
5. Keine Vererbung für Querschnittslogik
Cross-Cutting Concerns werden komponiert, nicht vererbt.
Verboten:
BaseComponent- Lifecycle-Basisklassen
- Infrastruktur-Hierarchien
Erlaubt:
- DI
- Utility-Funktionen
- Interceptors
- RxJS-Operatoren
6. Seiteneffekte sind explizit isoliert
Nur Effects dürfen Seiteneffekte enthalten.
Nicht:
- Nebenwirkungen in
map - versteckte State-Änderungen
Sondern:
- klar benannte
effect() - klar isolierte Interaktionen
7. Komponenten sind flach
UI-Hierarchie strukturiert Darstellung, nicht Logik.
Keine:
- tiefen Vererbungsbäume
- Service-Gottklassen
- globale State-Container ohne Kontrolle
8. Services haben klaren Verantwortungsbereich
Service ist entweder:
- Datenquelle
- Adapter
- Orchestrator
Nicht alles gleichzeitig.
9. Datenfluss ist sichtbar
Der Weg der Daten muss lesbar sein.
Erkennbar durch:
vm$- Signals
- klar definierte Streams
Nicht durch:
- implizite Setter
- versteckte Service-Mutation
10. Komposition vor Hierarchie
Verhalten wird zusammengesetzt, nicht geerbt.
Beispiele:
- RxJS-Operatoren
- Utility-Funktionen
- funktionale Helper
- Signal-Computed
11. Minimale imperative Zonen
Imperativer Code ist erlaubt:
- bei IO
- bei Browser-APIs
- bei Effects
Aber:
Imperative Zonen sind klar abgegrenzt.
12. Testbarkeit als Architekturindikator
Eine Komponente ist architektonisch gesund, wenn:
- sie ohne DOM testbar ist
- kein versteckter Lifecycle notwendig ist
- kein Super-Call erforderlich ist
- Datenfluss klar ist
13. Kein Framework-Umgehen
Verboten:
- manuelle DOM-Manipulation
- ChangeDetection-Tricks
- private Angular-Interna
- Promise-Konvertierung reaktiver Flüsse
14. State ist explizit modelliert
State existiert:
- als Signal
- als Observable
- als klar definierte Struktur
Nicht:
- verteilt in Feldern
- implizit in Services
- global ohne Kontrolle
15. Architektur wächst flach, nicht hierarchisch
Wachstum bedeutet:
- neue Komposition
- neue Streams
- neue Ableitungen
Nicht:
- neue Basisklassen
- neue protected-Felder
- neue Vererbungsstufen
Zusammenfassung
Ein reifes Angular-Frontend:
- ist datenflussgetrieben
- minimiert Mutation
- vermeidet Hierarchie
- isoliert Seiteneffekte
- nutzt Komposition
- projiziert State
Leitgedanke
Frontend ist kein Objektmodell.
Es ist eine reaktive Projektionsebene.