0Pricing
Kotlin Academy · Lektion

Funktionale Domänenmodellierung mit Arrows Core-Typen

Modellieren Sie komplexe Domänen mit Either, NonEmptyList und der Validierung von Fehleransammlungen.

Funktionale Domänenmodellierung mit Arrows Core-Typen ist eine kostenlose Kotlin Academy-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Kotlin Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.

Was ist funktionale Domänenmodellierung?

Bei der funktionalen Domänenmodellierung werden algebraische Typen (Either, Option, Sealed Classes) verwendet, um Geschäftsregeln in Typen abzubilden. Ungültige Zustände können zur Compile-Zeit nicht dargestellt werden, und Fehler sind in Funktionssignaturen explizit angegeben – es gibt keine versteckten Exceptions.

Wertobjekte mit Inline-/Value-Klassen

Verwenden Sie Kotlin-Value-Klassen, um Primitive zu kapseln und Primitive Obsession zu vermeiden. Das Typsystem lehnt es ab, ein UserId zu übergeben, wenn ein PostId erwartet wird:

@JvmInline value class UserId(val value: Long)
@JvmInline value class PostId(val value: Long)

fun findUser(id: UserId): Either<UserError, User> = TODO()
// findUser(PostId(1L))  // Compile error!

Sealed Classes für Domänenfehler

Modellieren Sie Fehler als Hierarchien von Sealed Classes. Jede Unterklasse enthält nur die für diesen Fehlerfall relevanten Daten:

sealed class UserError {
    data class NotFound(val id: UserId) : UserError()
    data class EmailTaken(val email: String) : UserError()
    data class ValidationFailed(val field: String, val reason: String) : UserError()
}

Validated: Mehrere Fehler sammeln

Wenn Sie alle Validierungsfehler auf einmal melden möchten (statt nur den ersten), verwenden Sie Arrows Validated (oder zipOrAccumulate in der Raise-DSL). Dabei werden die Fehler in einer NonEmptyList gesammelt:

import arrow.core.Validated
import arrow.core.valid
import arrow.core.invalid

fun validateName(name: String): Validated<String, String> =
    if (name.isNotBlank()) name.valid() else "Name is blank".invalid()

Validierungen kombinieren

Verwenden Sie zip(), um mehrere Ergebnisse vom Typ Validated zu kombinieren. Wenn eines davon Invalid ist, werden alle Fehler gesammelt:

val result: Validated<NonEmptyList<String>, User> =
    validateName(name).zip(validateEmail(email)) { n, e -> User(n, e) }
        .mapLeft { it }

Ungültige Zustände nicht darstellbar machen

Anstatt einen User mit einer nullbaren email-Adresse und einem Flag isVerified zu verwenden, nutzen Sie versiegelte Unterklassen. So verhindert das Typsystem den Zugriff auf die E-Mail-Adresse eines nicht verifizierten Benutzers:

sealed class User {
    data class Unverified(val id: UserId, val pendingEmail: String) : User()
    data class Verified(val id: UserId, val email: String) : User()
}

Smart Constructors

Verwenden Sie Factory-Funktionen im Companion-Objekt, die Either oder Option zurückgeben, anstelle öffentlicher Konstruktoren. So stellen Sie sicher, dass sich Instanzen immer in einem gültigen Zustand befinden:

class Email private constructor(val value: String) {
    companion object {
        fun of(raw: String): Either<String, Email> =
            if (raw.contains("@") && raw.length <= 255) Email(raw).right()
            else "Invalid email format".left()
    }
}

Either und Option in einer Pipeline kombinieren

Eine reale Domänenoperation verknüpft typischerweise Repository-Abfragen (Option) mit Validierungen (Either). Verwenden Sie den Arrow-Block either { } mit .bind(), um sie übersichtlich zu verketten:

fun createPost(authorId: UserId, title: String, body: String): Either<PostError, Post> = either {
    val author = userRepo.findById(authorId).toEither { PostError.AuthorNotFound }.bind()
    val validTitle = validateTitle(title).bind()
    postRepo.save(Post(author, validTitle, body))
}

Unveränderlichkeit und Copy

Domänenentitäten sollten unveränderlich sein. Verwenden Sie Datenklassen und copy(), um neue Zustände abzuleiten. Arrows Lens (aus arrow-optics) ermöglicht komfortable verschachtelte Aktualisierungen ohne Mutation:

val updated = user.copy(email = "new@example.com")
// Arrow Optics:
val emailLens = User.email
val updatedWithLens = emailLens.set(user, "new@example.com")

Typsichere Konfiguration mit Sealed Classes

Modellieren Sie Varianten der Anwendungskonfiguration mit Sealed Classes, damit der Compiler Sie zwingt, jeden Fall zu behandeln:

sealed class DbConfig {
    data class Postgres(val url: String, val user: String, val pass: String) : DbConfig()
    data class InMemory(val dbName: String = "test") : DbConfig()
}

Vorteile auf einen Blick

Die funktionale Domänenmodellierung mit Arrows zentralen Typen bietet:

  • Keine NullPointerExceptions im Domänencode
  • In Funktionssignaturen sichtbare Fehler
  • Vollständige when-Prüfungen in Sealed-Hierarchien
  • Testbare reine Funktionen
  • Selbstdokumentierenden Code

Schnelltest

Was ist der wichtigste Vorteil einer sealed class-Hierarchie für Domänenfehler gegenüber dem Auslösen von Exceptions?

Zusammenfassung: Funktionale Domänenmodellierung mit Arrows zentralen Typen

Die wichtigsten Erkenntnisse:

  • Value-Klassen verhindern Primitive Obsession
  • Versiegelte Fehlerhierarchien machen Fehlerfälle vollständig und typsicher
  • Smart Constructors garantieren gültige Instanzen
  • either { }.bind() setzt fehleranfällige Operationen sauber zusammen
  • Unveränderliche Daten + copy() / Arrow Optics für sichere Zustandsübergänge

Häufig gestellte Fragen

Ist die Lektion „Funktionale Domänenmodellierung mit Arrows Core-Typen“ kostenlos?

Ja — der vollständige Text von „Funktionale Domänenmodellierung mit Arrows Core-Typen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Kotlin Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Funktionale Domänenmodellierung mit Arrows Core-Typen“?

Modellieren Sie komplexe Domänen mit Either, NonEmptyList und der Validierung von Fehleransammlungen. Du übst Kotlin Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Kotlin Academy zu starten?

Keine Vorkenntnisse erforderlich. Kotlin Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.

Wie lange dauert die Lektion „Funktionale Domänenmodellierung mit Arrows Core-Typen“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Kotlin Academy-Lektion Code schreiben und ausführen?

Ja. Jede Kotlin Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Either : Typsichere Fehlerbehandlung ohne Exceptions
  2. Arrow-Raise-DSL: Typisierte Fehler kombinieren
  3. Option und Nullable: Wann Sie welches verwenden
  4. Funktionale Domänenmodellierung mit Arrows Core-Typen
← Zurück zu Kotlin Academy