0Pricing
Scala for Backend Engineering & Functional Programming · บทเรียน

ตัวสร้างอัจฉริยะ

การสร้างพร้อมตรวจสอบความถูกต้อง

ตัวสร้างอัจฉริยะ เป็นบทเรียน Scala for Backend Engineering & Functional Programming ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Scala for Backend Engineering & Functional Programming และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน

การสร้างค่าที่ผ่านการตรวจสอบ

ตัวสร้างอัจฉริยะคือโรงงานที่ตรวจสอบอินพุตก่อนสร้างค่า โดยรับประกันว่าอินสแตนซ์ทุกตัวที่คุณถืออยู่จะตรงตามเงื่อนไขคงที่ของชนิด

  • ตัวสร้างดิบถูกซ่อนไว้
  • เปิดให้สร้างได้เฉพาะผ่านการตรวจสอบแล้ว
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))

ตัวสร้างส่วนตัว

การกำหนดตัวสร้างหลักเป็น private จะป้องกันไม่ให้ผู้เรียกข้ามการตรวจสอบ ออบเจกต์คู่หูจึงกลายเป็นจุดเข้าใช้งานเพียงจุดเดียว

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

การคืนค่า Option

การคืนค่า Option สื่อว่าการสร้างค่าอาจล้มเหลว ผู้เรียกต้องจัดการกับ None ดังนั้นข้อมูลที่ไม่ถูกต้องจะไม่ไหลผ่านไปอย่างเงียบ ๆ

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

การคืนค่า Either เพื่อแสดงรายละเอียดข้อผิดพลาด

เมื่อคุณต้องการอธิบายสาเหตุที่การตรวจสอบล้มเหลว ให้คืนค่า Either[Error, T] โดย Left จะเก็บข้อความอธิบาย

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

ตัวสร้างอัจฉริยะด้วย case class

case class ที่มีตัวสร้างส่วนตัวยังคงใช้งานได้ โปรดทราบว่า apply และ copy ที่สร้างขึ้นโดยอัตโนมัติก็ต้องควบคุมเช่นกัน ดังนั้นให้กำหนดโรงงานแบบกำหนดเองและเก็บตัวสร้างไว้เป็นส่วนตัว

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

การเชื่อมค่าที่ผ่านการตรวจสอบ

เนื่องจากตัวสร้างอัจฉริยะคืนค่า Option หรือ Either คุณจึงสามารถนำมาประกอบกันด้วยนิพจน์ความเข้าใจ for เพื่อสร้างออบเจกต์ที่ผ่านการตรวจสอบขนาดใหญ่ขึ้น

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

การปรับรูปแบบอินพุตให้เป็นมาตรฐาน

ตัวสร้างอัจฉริยะยังสามารถปรับข้อมูลให้เป็นมาตรฐานได้ เช่น ตัดช่องว่างหรือเปลี่ยนเป็นตัวพิมพ์เล็ก เพื่อให้อินสแตนซ์ทั้งหมดมีรูปแบบมาตรฐานเดียวกัน

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

เงื่อนไขคงที่มีผลตลอดอายุการใช้งาน

เมื่อค่าผ่านตัวสร้างอัจฉริยะแล้ว จะรับประกันว่าเงื่อนไขคงที่จะเป็นจริงตลอดอายุการใช้งาน โค้ดส่วนถัดไปจึงเชื่อถือค่าได้โดยไม่ต้องตรวจสอบซ้ำ

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

การผสานกับชนิดทึบแสง

หากต้องการค่าที่ผ่านการตรวจสอบโดยไม่มีต้นทุน ให้จับคู่ตัวสร้างอัจฉริยะกับชนิดทึบแสง จะไม่มีการจัดสรรออบเจกต์ตัวห่อหุ้ม แต่การตรวจสอบยังคงควบคุมการสร้างค่า

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

กฎการตรวจสอบหลายข้อ

ใช้การตรวจสอบหลายข้อเรียงตามลำดับ กฎแรกที่ล้มเหลวจะหยุดการทำงานและคืนข้อผิดพลาดที่ชัดเจน

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

ควรใช้ตัวสร้างอัจฉริยะเมื่อใด

ใช้เมื่อใดก็ตามที่ชนิดมีเงื่อนไขคงที่ซึ่งการสร้างค่าแบบดิบอาจละเมิดได้

  • ตัวเลขที่อยู่ในช่วง สตริงที่ไม่ว่าง และรหัสที่มีรูปแบบกำหนด
  • คืนค่า Option สำหรับผลใช่หรือไม่ใช่อย่างง่าย และ Either เมื่อต้องการเหตุผล
  • เก็บตัวสร้างดิบไว้เป็นส่วนตัว
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))

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ทดสอบความเข้าใจของคุณเกี่ยวกับตัวสร้างอัจฉริยะ

สรุปทบทวน

คุณได้เรียนรู้ตัวสร้างอัจฉริยะ

  • ตรวจสอบอินพุตในโรงงานคู่หู
  • ทำให้ตัวสร้างดิบเป็นส่วนตัว
  • คืนค่า Option หรือ Either เพื่อบังคับให้จัดการกรณีล้มเหลว
  • ปรับอินพุตให้เป็นรูปแบบมาตรฐานได้ตามต้องการ
  • จากนั้นเงื่อนไขคงที่จะเป็นจริงตลอดอายุการใช้งานของค่า
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))

คำถามที่พบบ่อย

บทเรียน “ตัวสร้างอัจฉริยะ” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ตัวสร้างอัจฉริยะ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Scala for Backend Engineering & Functional Programming ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ตัวสร้างอัจฉริยะ”

การสร้างพร้อมตรวจสอบความถูกต้อง คุณปฏิบัติ Scala for Backend Engineering & Functional Programming ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Scala for Backend Engineering & Functional Programming หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Scala for Backend Engineering & Functional Programming บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “ตัวสร้างอัจฉริยะ” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Scala for Backend Engineering & Functional Programming นี้ได้ไหม

ได้ บทเรียน Scala for Backend Engineering & Functional Programming ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การสร้างแบบจำลองด้วย ADT
  2. ตัวสร้างอัจฉริยะ
  3. ชนิดข้อมูลใหม่
  4. การประกอบโดเมน
← กลับไปที่ Scala for Backend Engineering & Functional Programming