Komponenten sind keine Use-Cases
Eine Komponente ist ein Darstellungselement.
Sie rendert Zustand.
Sie nimmt Nutzerinteraktion entgegen.
Sie sendet Intents nach außen.
Das klingt banal. Ist es aber nicht.
Denn in vielen Frontend-Anwendungen werden Komponenten schleichend zu kleinen Anwendungsservices mit Template. Sie validieren fachliche Regeln, transformieren Daten, rufen APIs auf, entscheiden über Navigation, zeigen Toasts, aktualisieren Listen und halten nebenbei noch lokalen Zustand zusammen.
Dann ist die Komponente keine Komponente mehr.
Sie ist ein Use-Case in Component-Verkleidung.

Was eine Komponente darf
Abschnitt betitelt „Was eine Komponente darf“Eine Komponente darf UI-Arbeit machen.
Das bedeutet:
- Daten anzeigen
- ViewModel konsumieren
- lokale UI-Zustände halten
- Nutzerinteraktionen entgegennehmen
- einfache UI-Events senden
- Darstellung abhängig vom Zustand ändern
Eine Komponente darf wissen, ob ein Dialog offen ist.
Sie darf wissen, welcher Tab aktiv ist.
Sie darf ein Formular rendern.
Sie darf einen Button deaktivieren, wenn das ViewModel sagt, dass eine Aktion nicht erlaubt ist.
Aber sie sollte nicht selbst entscheiden, was fachlich passieren muss, wenn jemand diesen Button klickt.
Das ist der entscheidende Punkt.
Der häufige Fehler
Abschnitt betitelt „Der häufige Fehler“So sieht der Drift oft aus:
@Component(...)export class OrderComponent { constructor( private http: HttpClient, private router: Router, private toast: ToastService, ) {}
async submitOrder(data: OrderData) { const validated = this.validate(data); // Business-Logik const enriched = this.enrich(validated); // Domänen-Transformation
await firstValueFrom( this.http.post('/api/orders', enriched), // Infrastruktur );
this.toast.success('Bestellung gespeichert'); // Seiteneffekt this.router.navigate(['/confirmation']); // Navigation }
private validate(data: OrderData) { // fachliche Regeln }
private enrich(data: OrderData) { // Domänen-Transformation }}Das sieht erstmal produktiv aus.
Alles steht an einem Ort. Man kann dem Ablauf folgen. Der Button klickt, die Methode läuft, fertig.
Nur ist dieser Ort der falsche.
Die Komponente kennt jetzt:
- fachliche Validierungsregeln
- Datenanreicherung
- HTTP-Infrastruktur
- Toast-Verhalten
- Navigation
- Ablaufreihenfolge des Use-Cases
Das ist kein Darstellungselement mehr.
Das ist ein Anwendungsfall mit HTML-Anhang.

Warum das gefährlich ist
Abschnitt betitelt „Warum das gefährlich ist“Das Problem ist nicht, dass die Komponente „viel Code“ hat.
Viel Code ist nur ein Symptom.
Das eigentliche Problem ist: Sie hat zu viele Gründe, sich zu ändern.
Wenn sich die Darstellung ändert, muss die Komponente geändert werden. Wenn sich die fachliche Regel ändert, muss die Komponente geändert werden. Wenn sich die API ändert, muss die Komponente geändert werden. Wenn sich die Navigation ändert, muss die Komponente geändert werden. Wenn sich Toast-Verhalten ändert, muss die Komponente geändert werden.
Das ist schlechte Kopplung.
Nicht, weil irgendein Architekturdiagramm beleidigt ist. Sondern weil Änderungen in Bereiche laufen, in denen sie teuer sind.
Komponenten sind oft schwerer zu testen, stärker ans Framework gebunden und näher am DOM. Genau dort möchte man fachliche Abläufe nicht verstecken.
Die bessere Frage
Abschnitt betitelt „Die bessere Frage“Die Frage ist nicht:
Darf eine Komponente eine Methode haben?
Natürlich darf sie das.
Die bessere Frage ist:
Trifft diese Methode eine fachliche Entscheidung?
Wenn ja, gehört sie wahrscheinlich nicht in die Komponente.
Eine Komponentenmethode wie diese ist unkritisch:
openDetails() { this.detailsVisible.set(true);}Das ist UI-Zustand.
Eine Methode wie diese ist verdächtig:
submitOrder(data: OrderData) { if (data.items.length === 0) { this.toast.error('Bestellung ohne Positionen ist nicht erlaubt'); return; }
const payload = this.mapToPayload(data); this.http.post('/api/orders', payload).subscribe(() => { this.router.navigate(['/confirmation']); });}Hier passiert fachliche Regel, Mapping, Infrastruktur und Orchestrierung.
Das ist kein UI-Verhalten mehr.
Komponenten senden Intents
Abschnitt betitelt „Komponenten senden Intents“Eine robuste Komponente formuliert nicht den ganzen Ablauf.
Sie sendet eine Absicht.
@Component(...)export class OrderComponent { readonly vm = this.facade.vm;
constructor(private readonly facade: OrderFacade) {}
submit(data: OrderData) { this.facade.submitOrder(data); }}Die Komponente sagt damit nur:
Der Nutzer möchte eine Bestellung absenden.
Sie weiß nicht, ob danach ein HTTP-Call passiert. Sie weiß nicht, ob ein Toast erscheint. Sie weiß nicht, ob navigiert wird. Sie weiß nicht, ob ein Reload ausgelöst wird.
Und genau das ist der Punkt.

Wer orchestriert dann?
Abschnitt betitelt „Wer orchestriert dann?“Nicht die Komponente.
Je nach Architektur kann das eine Facade, ein Store, ein Use-Case-Service oder eine Application-Schicht sein.
Der Name ist weniger wichtig als die Verantwortung.
Component -> sendet Intent
Facade / Store -> koordiniert Zustand und UI-nahe Abläufe
Use Case / Application Service -> führt fachlichen Ablauf aus
Infrastructure -> spricht mit API, Storage, externen SystemenOder kompakter:
Component → Facade → Use Case → InfrastructureDie Komponente ist der Rand des Systems.
Sie ist nicht das System.
Was gehört nicht in Komponenten?
Abschnitt betitelt „Was gehört nicht in Komponenten?“Als Faustregel würde ich diese Dinge aus Komponenten heraushalten:
- HTTP-Aufrufe
- Repository-Zugriffe
- DTO-Mapping
- fachliche Validierung
- Domänen-Transformationen
- komplexe Berechnungen
- Event-Orchestrierung
- Reload-Ketten
- Toast- und Navigationsentscheidungen als Teil eines Use-Cases
- manuelle Synchronisierung mehrerer Datenquellen
- Berechtigungslogik, die über einfache Anzeigeentscheidungen hinausgeht
Nicht jeder einzelne Verstoß ist sofort ein Drama.
Aber wenn mehrere dieser Dinge zusammenkommen, ist die Komponente wahrscheinlich über ihre Rolle hinausgewachsen.

Was darf in Komponenten bleiben?
Abschnitt betitelt „Was darf in Komponenten bleiben?“Nicht alles muss ausgelagert werden.
Sonst entsteht nur Architekturtheater.
In Komponenten bleiben dürfen:
- lokale Sichtbarkeit eines Dialogs
- aktiver Tab
- Hover-/Focus-Zustände
- einfache UI-Interaktion
- Weitergabe eines Button-Klicks
- Konsum eines ViewModels
- sehr einfache Darstellungshilfen
Beispiel:
@Component(...)export class OrderDialogComponent { readonly dialogVisible = signal(false);
open() { this.dialogVisible.set(true); }
close() { this.dialogVisible.set(false); }
submit(formValue: OrderFormValue) { this.submitted.emit(formValue); }}Das ist UI-Verhalten.
Die Komponente entscheidet nicht, ob die Bestellung fachlich gültig ist, wie das API-Payload aussieht oder wohin nach Erfolg navigiert wird.
Warum Tests besser werden
Abschnitt betitelt „Warum Tests besser werden“Wenn Use-Cases in Komponenten stecken, müssen Tests durch die UI-Schicht.
Dann testet man plötzlich DOM, Framework-Lifecycle, Service-Mocks, Router, Toasts und fachliche Regeln in einem Test.
Das ist schwerfällig.
Wenn Komponenten nur ViewModels rendern und Intents senden, werden Tests kleiner:
- Komponententests prüfen Darstellung.
- Use-Case-Tests prüfen fachliche Abläufe.
- Mapper-Tests prüfen Übersetzung.
- Store-/Facade-Tests prüfen Zustands- und Event-Flüsse.
Jede Schicht wird dort getestet, wo ihre Verantwortung liegt.
Das ist kein Selbstzweck. Es macht Tests schneller, stabiler und lesbarer.
Der wichtige Unterschied
Abschnitt betitelt „Der wichtige Unterschied“Eine Komponente darf eine Interaktion auslösen.
Sie sollte aber nicht den gesamten fachlichen Ablauf besitzen.
Das ist der Unterschied zwischen:
submit(data) { this.facade.submitOrder(data);}und:
submit(data) { const validated = this.validate(data); const payload = this.map(validated);
this.http.post('/api/orders', payload).subscribe(() => { this.toast.success('Gespeichert'); this.router.navigate(['/confirmation']); this.reload(); });}Im ersten Fall äußert die Komponente eine Absicht.
Im zweiten Fall besitzt sie den Use-Case.
Komponenten sind keine Use-Cases.
Sie sind der Rand zur UI.
Sie rendern Zustand. Sie nehmen Interaktionen entgegen. Sie senden Intents.
Aber sie orchestrieren keine Business-Logik, keine Infrastruktur und keine fachlichen Abläufe.
Eine gute Komponente ist fast langweilig:
ViewModel rein.Intent raus.Rendering dazwischen.Das ist nicht weniger Architektur.
Das ist genau der Punkt von Architektur.