Zurück zur Startseite

UseCase in der Backend-Entwicklung: Strukturierung der Geschäftslogik

Der Artikel erklärt das UseCase-Muster zur Beschreibung von Geschäftszenarien in Backend-Anwendungen. Er behandelt Struktur, Vorteile, Einschränkungen und Implementierungsbeispiele in PHP und Laravel, einschließlich Testen und Code-Organisation.

UseCase: Wie man Geschäftsprozesse im Code für Entwickler beschreibt
Advertisement 728x90

UseCase-Pattern: Geschäftslogik im Backend strukturieren

Das UseCase-Pattern ist ein Architekturansatz, um Geschäftszenarien in Anwendungen klar zu definieren. Es organisiert den Code um konkrete Systemaktionen – wie das Erstellen einer Bestellung oder die Benutzerregistrierung – statt abstrakter technischer Operationen. Dieser Ansatz verbessert die Lesbarkeit, vereinfacht Tests und skaliert Projekte effektiv, besonders in komplexen Backend-Systemen.

Was ist UseCase und wofür lohnt es sich?

Ein UseCase stellt ein vollständiges Geschäftszenario in der Anwendungsschicht dar. Er steuert eine Abfolge von Schritten und delegiert Geschäftsregeln an Domänen-Services und Entities. Statt einer niedrigstufigen „Datenbank schreiben“-Operation beschreibt ein UseCase „Benutzer erstellt Bestellung“. So verhindert man, dass sich Geschäftslogik bei wachsendem Projekt über Controller und Services ausbreitet. Ohne klare Szenario-Grenzen wird der Code schwer verständlich und wartbar.

Wichtige Vorteile des UseCase-Patterns:

Google AdInline article slot
  • Klare Struktur: Das System wird durch explizite Geschäftsfunktionen definiert, nicht durch vage Abstraktionen wie Service oder Manager.
  • Bessere Lesbarkeit: Die Architektur spiegelt die Geschäftslogik wider und beantwortet leicht „Was kann diese App?“.
  • Einfachere Tests: Integrationstests auf Szenariosebene prüfen den gesamten Nutzerflow, ohne Geschäftsprozesse zu zerlegen.

Einschränkungen und Best Practices

Vermeiden Sie Aufrufe eines UseCases aus einem anderen, um versteckte Abhängigkeiten zu verhindern und sie nicht zu wiederverwendbaren Logikblöcken zu machen. In komplexen Szenarien sind zyklische Abhängigkeiten okay, solange Szenarien explizit bleiben. Für wiederverwendbare Logik extrahieren Sie diese in dedizierte Services oder Domänen-Komponenten, die in mehreren UseCases genutzt werden können.

Wo UseCases aufrufen:

  • Controller
  • Console Command
  • Job
  • Event Listener

UseCase dient als Einstiegspunkt in die Geschäftslogik Ihrer App und vermittelt externe Interaktionen mit dem System.

Google AdInline article slot

Warum Services allein nicht reichen

Services funktionieren bei einfachen Projekten gut, aber bei wachsender Geschäftslogik treten Probleme auf. Was als einfaches „in Datenbank speichern“ für Bestellungen beginnt, wächst zu Prüfungen auf Lagerbestand, Rabattanwendung, Kontostornierung und Benachrichtigungen. Das führt zu God-Objects – Klassen voller Abhängigkeiten, Methoden und Nebenwirkungen –, die den Code unlesbar und schwer testbar machen.

UseCase folgt einer einfachen Regel: Ein UseCase = ein Geschäftsprozess. Duplizierte Logik wandert in geteilte Services oder Domänen-Komponenten, um den Code bei steigender Komplexität handhabbar zu halten.

UseCase-Struktur in PHP und Laravel

Ein typischer UseCase besteht aus drei Teilen:

Google AdInline article slot
  • Handler: Steuert Szenario-Schritte und Bedingungen, ohne eigene Domänen-Geschäftslogik.
  • DataInput: Eingabe-Datenobjekt ohne Logik – nur typisierte, vorzugsweise unveränderliche Daten.
  • DataOutput: Ergebnis-Objekt mit klarem Vertrag (z. B. DTO).

Beispiel: Bestellung erstellen:

class StoreOrderDataInput
{
    public function __construct(
        public readonly int $userId,
        public readonly array $items,
    ) {}
}

class StoreOrderDataOutput
{
    public function __construct(
        public readonly int $orderId,
        public readonly string $status,
    ) {}
}

class StoreOrderHandler
{
    public function __construct(
        private OrderRepository $orders
    ) {}

    public function handle(StoreOrderDataInput $input): StoreOrderDataOutput
    {
        $order = new Order(
            userId: $input->userId,
        );

        $orderSaved = $this->orders->save($order);

        return new StoreOrderDataOutput(
            orderId: $orderSaved->id,
            status: $orderSaved->status
        );
    }
}

UseCases in Projekten organisieren und testen

In Laravel speichern Sie UseCases in einer Struktur wie app/UseCases/V1 mit Versionierung für sichere Vertragsänderungen. Unterverzeichnisse beantworten „Was kann das System?“ – z. B. StoreOrder, CancelOrder, RegisterUser. Das spiegelt Geschäftsfunktionen wider, nicht technische Details.

Das Testen von UseCases gelingt unkompliziert mit Integrationstests auf Szenariosebene. Beispieltest für StoreOrderHandler:

use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;

class StoreOrderFeatureTest extends TestCase
{
    use RefreshDatabase;

    public function testUserCanCreateOrder(): void
    {
        $user = User::factory()->create();

        $payload = [
            'items' => [
                ['id' => 10, 'qty' => 2],
                ['id' => 15, 'qty' => 1],
            ],
        ];

        $response = $this->actingAs($user)
            ->postJson('/api/orders', $payload);

        $response->assertStatus(200);
        $response->assertJsonStructure([
            'orderId',
            'status'
        ]);
        $this->assertDatabaseHas('orders', [
            'user_id' => $user->id
        ]);
    }
}

Wichtige Erkenntnisse

  • UseCase definiert Geschäftszenarien, nicht technische Operationen, für eine saubere App-Struktur.
  • Es löst Logik-Verwucherung in großen Projekten und hält Code wartbar.
  • Ein UseCase = ein Geschäftsprozess, mit geteilter Logik in Services.
  • Tests werden einfacher durch Integrationstests für komplette Szenarien.
  • Projektstruktur spiegelt Geschäftsfeatures, beschleunigt Einarbeitung.

— Editorial Team

Advertisement 728x90

Weiterlesen