0Pricing
Scala for Backend Engineering & Functional Programming · Pelajaran

Konstruktor Cerdas

Konstruksi tervalidasi

Konstruktor Cerdas adalah pelajaran Scala for Backend Engineering & Functional Programming gratis di CoddyKit. Ini adalah pelajaran 2 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.

Konstruksi yang Telah Divalidasi

Konstruktor cerdas adalah factory yang memvalidasi input sebelum menghasilkan nilai. Konstruktor ini menjamin bahwa setiap instance yang Anda pegang memenuhi invariant tipe tersebut.

  • Konstruktor mentah disembunyikan.
  • Hanya pembuatan yang telah divalidasi yang bersifat publik.
class Age private (val value: Int)
object Age:
  def of(v: Int): Option[Age] =
    if v >= 0 then Some(new Age(v)) else None

object Main:
  def main(args: Array[String]): Unit =
    println(Age.of(30).map(_.value))

Konstruktor Privat

Menandai konstruktor utama sebagai private mencegah pemanggil melewati validasi. Objek pendamping menjadi satu-satunya titik masuk.

class Percentage private (val value: Int)
object Percentage:
  def of(v: Int): Option[Percentage] =
    if v >= 0 && v <= 100 then Some(new Percentage(v)) else None

object Main:
  def main(args: Array[String]): Unit =
    println(Percentage.of(50).map(_.value))
    println(Percentage.of(150))

Mengembalikan Option

Mengembalikan Option menandakan bahwa konstruksi mungkin gagal. Pemanggil harus menangani None, sehingga data tidak valid tidak pernah mengalir secara diam-diam.

class NonEmpty private (val value: String)
object NonEmpty:
  def of(s: String): Option[NonEmpty] =
    if s.nonEmpty then Some(new NonEmpty(s)) else None

object Main:
  def main(args: Array[String]): Unit =
    println(NonEmpty.of("").map(_.value))
    println(NonEmpty.of("hi").map(_.value))

Mengembalikan Either untuk Detail Error

Jika Anda ingin menjelaskan mengapa validasi gagal, kembalikan Either[Error, T]. Left membawa pesan deskriptif.

class Username private (val value: String)
object Username:
  def of(s: String): Either[String, Username] =
    if s.isEmpty then Left("empty")
    else if s.length > 10 then Left("too long")
    else Right(new Username(s))

object Main:
  def main(args: Array[String]): Unit =
    println(Username.of(""))
    println(Username.of("ada").map(_.value))

Konstruktor Cerdas dengan case class

case class dengan konstruktor privat tetap dapat digunakan. Perhatikan bahwa apply dan copy yang dibuat secara otomatis juga harus dikendalikan, jadi definisikan factory khusus dan pertahankan konstruktor tetap privat.

case class Email private (value: String)
object Email:
  def of(s: String): Option[Email] =
    if s.contains("@") then Some(Email(s)) else None

object Main:
  def main(args: Array[String]): Unit =
    println(Email.of("a@b.com"))
    println(Email.of("bad"))

Merangkai Nilai yang Telah Divalidasi

Karena konstruktor cerdas mengembalikan Option atau Either, Anda dapat menyusunnya dengan comprehension for untuk membangun objek tervalidasi yang lebih besar.

case class Name private (value: String)
object Name:
  def of(s: String): Option[Name] =
    if s.nonEmpty then Some(Name(s)) else None

case class Person(name: Name, age: Int)

object Main:
  def make(n: String): Option[Person] =
    for nm <- Name.of(n) yield Person(nm, 20)

  def main(args: Array[String]): Unit =
    println(Main.make("Bob"))

Menormalkan Input

Konstruktor cerdas juga dapat menormalkan data, misalnya dengan menghapus spasi atau mengubah huruf menjadi kecil, sehingga semua instance memiliki bentuk kanonis.

case class Tag private (value: String)
object Tag:
  def of(s: String): Option[Tag] =
    val clean = s.trim.toLowerCase
    if clean.nonEmpty then Some(Tag(clean)) else None

object Main:
  def main(args: Array[String]): Unit =
    println(Tag.of("  Scala  "))

Invariant Berlaku Selamanya

Setelah sebuah nilai melewati konstruktor cerdas, invariant-nya dijamin berlaku sepanjang masa hidupnya. Kode lanjutan dapat memercayai nilai tersebut tanpa memeriksanya lagi.

case class PositiveInt private (value: Int)
object PositiveInt:
  def of(n: Int): Option[PositiveInt] =
    if n > 0 then Some(PositiveInt(n)) else None

object Main:
  def doubleIt(p: PositiveInt): Int = p.value * 2 // always positive

  def main(args: Array[String]): Unit =
    PositiveInt.of(5).foreach(p => println(Main.doubleIt(p)))

Menggabungkan dengan Tipe Opaque

Untuk nilai tervalidasi tanpa biaya, padukan konstruktor cerdas dengan tipe opaque. Tidak ada objek pembungkus yang dialokasikan, tetapi validasi tetap menjadi syarat pembuatan.

object Domain:
  opaque type Score = Int
  def of(n: Int): Option[Score] =
    if n >= 0 && n <= 100 then Some(n) else None
  extension (s: Score) def value: Int = s

object Main:
  def main(args: Array[String]): Unit =
    println(Domain.of(88).map(_.value))

Beberapa Aturan Validasi

Terapkan beberapa pemeriksaan secara berurutan. Aturan pertama yang gagal akan menghentikan proses dan mengembalikan error yang jelas.

object Password:
  def of(s: String): Either[String, String] =
    if s.length < 8 then Left("too short")
    else if !s.exists(_.isDigit) then Left("need a digit")
    else Right(s)

object Main:
  def main(args: Array[String]): Unit =
    println(Password.of("abc"))
    println(Password.of("abcdef12"))

Kapan Menggunakan Konstruktor Cerdas

Gunakan konstruktor cerdas setiap kali sebuah tipe memiliki invariant yang dapat dilanggar oleh konstruksi mentah.

  • Angka berbatas, string tidak kosong, id berformat.
  • Kembalikan Option untuk jawaban ya/tidak sederhana, dan Either untuk alasannya.
  • Pertahankan konstruktor mentah tetap privat.
case class Port private (value: Int)
object Port:
  def of(n: Int): Option[Port] =
    if n >= 1 && n <= 65535 then Some(Port(n)) else None

object Main:
  def main(args: Array[String]): Unit =
    println(Port.of(8080))
    println(Port.of(70000))

Pemeriksaan Singkat

Uji pemahaman Anda tentang konstruktor cerdas.

Ringkasan

Anda telah mempelajari konstruktor cerdas.

  • Validasi input di factory pendamping.
  • Jadikan konstruktor mentah privat.
  • Kembalikan Option atau Either untuk memaksa penanganan kegagalan.
  • Secara opsional, normalkan input ke bentuk kanonis.
  • Dengan demikian, invariant berlaku sepanjang masa hidup nilai.
case class Even private (value: Int)
object Even:
  def of(n: Int): Option[Even] =
    if n % 2 == 0 then Some(Even(n)) else None

object Main:
  def main(args: Array[String]): Unit =
    println(Even.of(4))
    println(Even.of(5))

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Konstruktor Cerdas” gratis?

Ya — teks lengkap “Konstruktor Cerdas” 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 “Konstruktor Cerdas”?

Konstruksi tervalidasi 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 2 dari 4.

Berapa lama pelajaran “Konstruktor Cerdas” 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