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
Optionuntuk jawaban ya/tidak sederhana, danEitheruntuk 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
OptionatauEitheruntuk 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
- Pemodelan dengan ADT
- Konstruktor Cerdas
- Newtype
- Menggabungkan Domain