0Pricing
Kotlin Academy · レッスン

Arrowのコア型による関数型ドメインモデリング

Either、NonEmptyList、検証済みエラーの蓄積を使用して、複雑なドメインをモデル化します。

「Arrowのコア型による関数型ドメインモデリング」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。

関数型ドメインモデリングとは

関数型ドメインモデリングでは、代数的データ型(Either、Option、sealed class)を使って、ビジネスルールを型に組み込みます。無効な状態はコンパイル時に表現できなくなり、エラーは関数シグネチャで明示されます。隠れた例外はありません。

インラインクラス/値クラスによる値オブジェクト

プリミティブ型への過度な依存を防ぐために、Kotlin の値クラスでプリミティブ型をラップしてください。PostId が必要な場所に UserId を渡すと、型システムによって拒否されます:

@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 classを使う

エラーを sealed class の階層としてモデル化してください。各サブクラスには、そのエラーケースに関係するデータだけを持たせます:

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:複数のエラーを蓄積する

最初のエラーだけでなく、すべての検証エラーを一度に報告したい場合は、Arrow の Validated(または Raise DSL の zipOrAccumulate)を使用してください。エラーは NonEmptyList に蓄積されます:

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()

検証を組み合わせる

複数の Validated 結果を組み合わせるには zip() を使用してください。いずれかが Invalid の場合は、すべてのエラーが蓄積されます:

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

不正な状態を表現不可能にする

null 許容の email と isVerified フラグを持つ User の代わりに、sealed class のサブクラスを使用してください。これにより、未検証ユーザーのメールアドレスにアクセスできないよう、型システムで防止できます:

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

スマートコンストラクター

公開コンストラクターの代わりに、Either または Option を返す companion object のファクトリ関数を使用してください。これにより、インスタンスが常に有効な状態になることを保証できます:

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とOptionを組み合わせる

実際のドメイン操作では通常、リポジトリ検索(Option)と検証(Either)を連鎖させます。Arrow の either { } ブロックと .bind() を使用すると、これらを自然な流れで組み合わせられます:

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))
}

不変性とcopy()

ドメインエンティティは不変にしてください。データクラスと copy() を使って、新しい状態を生成します。Arrow の Lens(arrow-optics の一部)を使うと、変更を伴わずにネストされた値を簡潔に更新できます:

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

sealed classによる型安全な設定

アプリケーション設定のバリエーションを sealed class でモデル化すると、コンパイラによってすべてのケースの処理が強制されます:

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

メリットの概要

Arrow のコア型を使った関数型ドメインモデリングには、次のメリットがあります:

  • ドメインコードで null ポインタ例外が発生しません
  • エラーが関数シグネチャに現れます
  • sealed class の階層に対する when の網羅的なチェックが可能です
  • テスト可能な純粋関数を使用できます
  • コード自体が仕様を説明します

確認問題

例外をスローする方法と比べて、ドメインエラーに sealed class の階層を使う主なメリットは何ですか?

復習:Arrowのコア型による関数型ドメインモデリング

要点:

  • 値クラスによって、プリミティブ型への過度な依存を防げます
  • sealed class によるエラー階層によって、失敗ケースを網羅的かつ型安全に扱えます
  • スマートコンストラクターによって、有効なインスタンスだけを生成できます
  • either { }.bind() によって、失敗する可能性のある操作を簡潔に組み合わせられます
  • 不変データと copy()/Arrow Optics によって、安全に状態を遷移できます

よくある質問

「Arrowのコア型による関数型ドメインモデリング」レッスンは無料ですか?

はい。「Arrowのコア型による関数型ドメインモデリング」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。

「Arrowのコア型による関数型ドメインモデリング」で何を学びますか?

Either、NonEmptyList、検証済みエラーの蓄積を使用して、複雑なドメインをモデル化します。 ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Kotlin Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「Arrowのコア型による関数型ドメインモデリング」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このKotlin Academyレッスンでコードを書いて実行できますか?

はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Either :例外を使わない型付きエラー処理
  2. Arrow Raise DSL:型付きエラーの合成
  3. OptionとNullable:それぞれを使う場面
  4. Arrowのコア型による関数型ドメインモデリング
← Kotlin Academyに戻る