0Pricing
Scala for Backend Engineering & Functional Programming · Pelajaran

Pemodelan dengan ADT

Membuat keadaan ilegal tidak dapat direpresentasikan

Pemodelan dengan ADT adalah pelajaran Scala for Backend Engineering & Functional Programming gratis di CoddyKit. Ini adalah pelajaran 1 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 Scala for Backend Engineering & Functional Programming, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Scala for Backend Engineering & Functional Programming mencakup 4 pelajaran total.

Tipe Data Aljabar

Tipe data aljabar (ADT) adalah dasar pemodelan domain fungsional. Tipe ini menggabungkan tipe produk (AND) dan tipe jumlah (OR) untuk mendeskripsikan data dengan tepat.

  • Produk: record dengan beberapa bidang.
  • Jumlah: pilihan di antara beberapa varian.
case class Point(x: Int, y: Int) // product type

object Main:
  def main(args: Array[String]): Unit =
    println(Point(1, 2))

Tipe Produk

Tipe produk menggabungkan beberapa nilai. Dalam Scala, case class merupakan produk: sebuah instance menyimpan semua bidangnya sekaligus.

case class User(name: String, age: Int)

object Main:
  def main(args: Array[String]): Unit =
    val u = User("Ada", 36)
    println(u.name)
    println(u.age)

Tipe Jumlah

Tipe jumlah adalah nilai yang tepat merupakan salah satu dari beberapa varian. Enum Scala 3 menyatakan hal ini secara langsung.

enum PaymentMethod:
  case Cash
  case Card(number: String)
  case Crypto(wallet: String)

object Main:
  def main(args: Array[String]): Unit =
    val p: PaymentMethod = PaymentMethod.Card("1234")
    println(p)

Membuat Keadaan Ilegal Tidak Dapat Direpresentasikan

Prinsip utamanya: rancang tipe sehingga data tidak valid bahkan tidak dapat dibuat. Jika sistem tipe melarang keadaan yang buruk, Anda tidak perlu memeriksanya saat runtime.

enum Connection:
  case Disconnected
  case Connected(sessionId: String)

object Main:
  def main(args: Array[String]): Unit =
    // No way to have a sessionId while Disconnected
    val c: Connection = Connection.Connected("abc")
    println(c)

Rancangan Buruk vs Rancangan Baik

Record datar dengan bidang yang dapat bernilai null membuka peluang munculnya keadaan ilegal. Memodelkan setiap kasus sebagai varian menghilangkan keadaan tersebut.

  • Buruk: case class Conn(connected: Boolean, sessionId: String) memungkinkan connected=false dengan sessionId.
  • Baik: tipe jumlah mengaitkan bidang dengan keadaan yang tepat.
enum Door:
  case Open
  case Closed
  case Locked(key: String)

object Main:
  def main(args: Array[String]): Unit =
    val d: Door = Door.Locked("k1")
    println(d)

Menggabungkan Produk dan Jumlah

Model nyata dapat menempatkan produk di dalam jumlah, dan sebaliknya. Setiap varian dapat membawa produk bidangnya sendiri.

case class Address(city: String, zip: String)

enum Contact:
  case Email(value: String)
  case Postal(address: Address)

object Main:
  def main(args: Array[String]): Unit =
    val c: Contact = Contact.Postal(Address("Paris", "75001"))
    println(c)

Pencocokan Pola ADT

Anda menggunakan ADT dengan pencocokan pola. Karena tipenya tertutup, kompilator akan memperingatkan jika Anda melewatkan sebuah varian.

enum Shape:
  case Circle(r: Double)
  case Rect(w: Double, h: Double)

object Main:
  def area(s: Shape): Double = s match
    case Shape.Circle(r)  => 3.14159 * r * r
    case Shape.Rect(w, h) => w * h

  def main(args: Array[String]): Unit =
    println(area(Shape.Rect(2, 3)))

ADT Rekursif

ADT dapat merujuk pada dirinya sendiri, sehingga secara alami dapat memodelkan pohon, list, dan expression.

enum Expr:
  case Num(value: Int)
  case Add(left: Expr, right: Expr)

object Main:
  def eval(e: Expr): Int = e match
    case Expr.Num(v)    => v
    case Expr.Add(l, r) => eval(l) + eval(r)

  def main(args: Array[String]): Unit =
    val e = Expr.Add(Expr.Num(2), Expr.Num(3))
    println(eval(e))

Opsionalitas dengan Option

Gunakan Option, bukan null, untuk memodelkan bidang yang mungkin tidak ada. Tipe ini membuat ketiadaan menjadi eksplisit dan memaksa penanganannya.

case class Profile(name: String, nickname: Option[String])

object Main:
  def main(args: Array[String]): Unit =
    val p = Profile("Grace", None)
    println(p.nickname.getOrElse("(none)"))

Memodelkan Kuantitas dengan Tepat

Gantilah penggunaan primitif secara berlebihan. Alih-alih menggunakan Int dan String mentah, bungkus kuantitas yang bermakna agar tipe mendokumentasikan maksud dan mencegah kekeliruan.

case class Quantity(value: Int)
case class Price(cents: Long)
case class LineItem(qty: Quantity, price: Price)

object Main:
  def main(args: Array[String]): Unit =
    val item = LineItem(Quantity(3), Price(500))
    println(item)

Mengapa ADT Penting

ADT memberikan kebenaran dan kejelasan.

  • Keadaan ilegal tidak dapat dibuat.
  • Pencocokan menyeluruh menemukan kasus yang terlewat saat kompilasi.
  • Bentuk data mendokumentasikan domain.
enum OrderStatus:
  case Pending
  case Shipped(tracking: String)
  case Delivered(at: Long)

object Main:
  def main(args: Array[String]): Unit =
    val s: OrderStatus = OrderStatus.Shipped("TRK1")
    println(s)

Pemeriksaan Singkat

Uji pemahaman Anda tentang pemodelan berbasis ADT.

Ringkasan

Anda telah mempelajari pemodelan domain dengan ADT.

  • Tipe produk (case class) menggabungkan bidang dengan AND.
  • Tipe jumlah (enum) menawarkan pilihan dengan OR.
  • Sarangankan keduanya untuk memodelkan domain yang kaya dan struktur rekursif.
  • Gunakan Option, bukan null.
  • Rancang tipe agar keadaan ilegal tidak dapat direpresentasikan.
enum Event:
  case Created(id: Int)
  case Deleted(id: Int, reason: String)

object Main:
  def describe(e: Event): String = e match
    case Event.Created(id)         => s"created $id"
    case Event.Deleted(id, reason) => s"deleted $id: $reason"

  def main(args: Array[String]): Unit =
    println(describe(Event.Deleted(1, "spam")))

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Pemodelan dengan ADT” gratis?

Ya — teks lengkap “Pemodelan dengan ADT” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Scala for Backend Engineering & Functional Programming, upgrade ke CoddyKit PRO. Kursus Scala for Backend Engineering & Functional Programming mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Pemodelan dengan ADT”?

Membuat keadaan ilegal tidak dapat direpresentasikan Kamu berlatih Scala for Backend Engineering & Functional Programming 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 Scala for Backend Engineering & Functional Programming?

Tidak diperlukan pengalaman sebelumnya. Scala for Backend Engineering & Functional Programming 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 1 dari 4.

Berapa lama pelajaran “Pemodelan dengan ADT” 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 Scala for Backend Engineering & Functional Programming ini?

Ya. Setiap pelajaran Scala for Backend Engineering & Functional Programming 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. Pemodelan dengan ADT
  2. Konstruktor Cerdas
  3. Newtype
  4. Menggabungkan Domain
← Kembali ke Scala for Backend Engineering & Functional Programming