0Pricing
Kotlin Academy · Pelajaran

Pemodelan Domain Fungsional dengan Tipe Inti Arrow

Modelkan domain kompleks menggunakan Either, NonEmptyList, dan akumulasi error tervalidasi.

Pemodelan Domain Fungsional dengan Tipe Inti Arrow adalah pelajaran Kotlin Academy gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Kotlin Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Kotlin Academy mencakup 4 pelajaran total.

Apa Itu Pemodelan Domain Fungsional?

Pemodelan domain fungsional menggunakan tipe aljabar (Either, Option, kelas tersegel) untuk menyandikan aturan bisnis ke dalam tipe. Keadaan yang tidak valid menjadi tidak dapat direpresentasikan saat kompilasi, dan kesalahan dinyatakan secara jelas dalam tanda tangan fungsi—tanpa pengecualian tersembunyi.

Objek Nilai dengan Kelas Inline/Nilai

Gunakan kelas nilai Kotlin untuk membungkus tipe primitif dan mencegah obsesi terhadap tipe primitif. Sistem tipe akan menolak penerusan UserId ketika yang diharapkan adalah PostId:

@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!

Kelas Tersegel untuk Kesalahan Domain

Modelkan kesalahan sebagai hierarki kelas tersegel. Setiap subkelas hanya membawa data yang relevan dengan kasus kesalahan tersebut:

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: Mengakumulasi Beberapa Kesalahan

Jika Anda ingin melaporkan semua kesalahan validasi sekaligus, bukan hanya kesalahan pertama, gunakan Validated milik Arrow (atau zipOrAccumulate dalam DSL Raise). Kesalahan tersebut dikumpulkan ke dalam 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()

Menggabungkan Validasi

Gunakan zip() untuk menggabungkan beberapa hasil Validated. Jika salah satunya adalah Invalid, semua kesalahan akan dikumpulkan:

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

Membuat Keadaan Ilegal Tidak Dapat Direpresentasikan

Alih-alih menggunakan User dengan email yang dapat bernilai null dan penanda isVerified, gunakan subkelas tersegel agar sistem tipe mencegah Anda mengakses email milik pengguna yang belum terverifikasi:

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

Konstruktor Cerdas

Gunakan fungsi pabrik pada objek pendamping yang mengembalikan Either atau Option, bukan konstruktor publik. Dengan begitu, instans selalu berada dalam keadaan yang valid:

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

Menggabungkan Either dan Option dalam Alur

Operasi domain nyata biasanya merangkai pencarian repositori (Option) dengan validasi (Either). Gunakan blok either { } milik Arrow bersama .bind() untuk menyusunnya dengan lancar:

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

Imutabilitas dan Copy

Entitas domain seharusnya tidak dapat diubah. Gunakan kelas data dan copy() untuk menghasilkan keadaan baru. Lens milik Arrow (dari arrow-optics) memungkinkan pembaruan bertingkat yang praktis tanpa mutasi:

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

Konfigurasi Aman Tipe dengan Kelas Tersegel

Modelkan varian konfigurasi aplikasi dengan kelas tersegel agar kompiler memaksa Anda menangani setiap kasus:

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

Manfaat Secara Ringkas

Pemodelan domain fungsional dengan tipe inti Arrow memberikan manfaat berikut:

  • Tidak ada pengecualian penunjuk null dalam kode domain
  • Kesalahan terlihat dalam tanda tangan fungsi
  • Pemeriksaan when yang mencakup semua kasus pada hierarki tersegel
  • Fungsi murni yang mudah diuji
  • Kode yang mendokumentasikan dirinya sendiri

Pemeriksaan Singkat

Apa manfaat utama menggunakan hierarki sealed class untuk kesalahan domain dibandingkan melempar pengecualian?

Rangkuman: Pemodelan Domain Fungsional dengan Tipe Inti Arrow

Inti pembelajaran:

  • Kelas nilai mencegah obsesi terhadap tipe primitif
  • Hierarki kesalahan tersegel membuat semua kasus kegagalan tercakup dan aman terhadap tipe
  • Konstruktor cerdas menjamin instans yang valid
  • either { }.bind() menyusun operasi yang dapat gagal dengan rapi
  • Data yang tidak dapat diubah + copy() / Arrow Optics untuk transisi keadaan yang aman

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Pemodelan Domain Fungsional dengan Tipe Inti Arrow” gratis?

Ya — teks lengkap “Pemodelan Domain Fungsional dengan Tipe Inti Arrow” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Kotlin Academy, upgrade ke CoddyKit PRO. Kursus Kotlin Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Pemodelan Domain Fungsional dengan Tipe Inti Arrow”?

Modelkan domain kompleks menggunakan Either, NonEmptyList, dan akumulasi error tervalidasi. Kamu berlatih Kotlin Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Kotlin Academy?

Tidak diperlukan pengalaman sebelumnya. Kotlin Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.

Berapa lama pelajaran “Pemodelan Domain Fungsional dengan Tipe Inti Arrow” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Kotlin Academy ini?

Ya. Setiap pelajaran Kotlin Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Either : Penanganan Error Bertipe Tanpa Exception
  2. DSL Raise Arrow: Menyusun Error Bertipe
  3. Option dan Nullable: Kapan Menggunakan Masing-Masing
  4. Pemodelan Domain Fungsional dengan Tipe Inti Arrow
← Kembali ke Kotlin Academy