0Pricing
Kotlin Academy · บทเรียน

ตัวแทน observable และ vetoable

ตอบสนองต่อการเปลี่ยนแปลงพร็อพเพอร์ตีด้วย observable และปฏิเสธตามเงื่อนไขด้วย vetoable

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

ทบทวนตัวแทนพร็อพเพอร์ตี

ตัวแทนพร็อพเพอร์ตีของ Kotlin ช่วยให้ออบเจ็กต์แยกต่างหากจัดการ getValue และ setValue ได้ Delegates.observable และ Delegates.vetoable เป็นตัวแทนในไลบรารีมาตรฐาน

import kotlin.properties.Delegates
var name: String by Delegates.observable("initial") { prop, old, new ->
    println("${prop.name}: $old -> $new")
}
fun main() { name = "Alice"; name = "Bob" }

ไวยากรณ์ของ observable

observable รับค่าเริ่มต้นและการเรียกกลับที่ถูกเรียกใช้ หลังจาก การเปลี่ยนแปลงแต่ละครั้ง พร้อมพร็อพเพอร์ตี ค่าเดิม และค่าใหม่

import kotlin.properties.Delegates
var score: Int by Delegates.observable(0) { _, old, new ->
    println("Score changed from $old to $new")
}
fun main() {
    score = 10
    score = 25
    score = 0
}

เรียกใช้การอัปเดตส่วนติดต่อผู้ใช้

ตัวแทนแบบ Observable เหมาะอย่างยิ่งสำหรับเรียกใช้การรีเฟรชส่วนติดต่อผู้ใช้เมื่อพร็อพเพอร์ตีต้นทางเปลี่ยนแปลง โดยไม่ต้องตั้งค่า LiveData ทั้งหมด

import kotlin.properties.Delegates
class ViewModel {
    var title: String by Delegates.observable("Loading") { _, _, new ->
        println("Render: $new") // pretend this updates UI
    }
}
fun main() {
    val vm = ViewModel()
    vm.title = "Home"
    vm.title = "Settings"
}

ไวยากรณ์ของ vetoable

vetoable จะเรียกใช้การเรียกกลับ ก่อน การกำหนดค่า หากการเรียกกลับส่งคืน false ค่าใหม่จะถูกปฏิเสธและคงค่าเดิมไว้

import kotlin.properties.Delegates
var age: Int by Delegates.vetoable(0) { _, old, new ->
    new >= 0 // reject negative ages
}
fun main() {
    age = 25; println(age)  // 25
    age = -1; println(age)  // 25 (rejected)
    age = 30; println(age)  // 30
}

การใช้การตรวจสอบร่วมกับ vetoable

ใช้ vetoable เพื่อบังคับใช้เงื่อนไขคงที่ของโดเมนในระดับพร็อพเพอร์ตี โดยไม่ต้องมีตรรกะการตรวจสอบจากภายนอก

import kotlin.properties.Delegates
var email: String by Delegates.vetoable("") { _, _, new ->
    new.contains("@")
}
fun main() {
    email = "user@example.com"; println(email) // set
    email = "invalid";          println(email) // still previous
}

บันทึกการเปลี่ยนแปลงด้วย observable

ใช้ observable สำหรับการบันทึกเพื่อตรวจสอบย้อนหลัง โดยบันทึกการเปลี่ยนแปลงสถานะทุกครั้งโดยอัตโนมัติและไม่ต้องแตะต้องตรรกะทางธุรกิจ

import kotlin.properties.Delegates
val log = mutableListOf<String>()
var status: String by Delegates.observable("IDLE") { _, old, new ->
    log.add("$old -> $new")
}
fun main() {
    status = "RUNNING"
    status = "DONE"
    println(log)
}

observable ในคลาส

ตัวแทนทั้งสองทำงานภายในเนื้อหาของคลาสได้เช่นเดียวกับพร็อพเพอร์ตีอื่น ๆ

import kotlin.properties.Delegates
class Counter {
    var count: Int by Delegates.observable(0) { _, old, new ->
        if (new > old) println("Incremented to $new")
        else println("Decremented to $new")
    }
}
fun main() {
    val c = Counter()
    c.count = 5
    c.count = 3
}

ใช้ vetoable เพื่อจำกัดช่วงค่า

จำกัดพร็อพเพอร์ตีตัวเลขให้อยู่ในช่วงค่าที่ถูกต้องด้วย vetoable

import kotlin.properties.Delegates
var volume: Int by Delegates.vetoable(50) { _, _, new ->
    new in 0..100
}
fun main() {
    volume = 80;  println(volume) // 80
    volume = 150; println(volume) // 80 (rejected)
    volume = 0;   println(volume) // 0
}

การเชื่อมตัวแทน

คุณสามารถรวมตรรกะของ observable ด้วยตนเองได้ โดยเขียนตัวแทนแบบกำหนดเองที่เรียกใช้ observable ภายใน และเพิ่มตรรกะพิเศษในแต่ละขั้นตอน

import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
class LoggedDelegate<T>(initial: T) : ReadWriteProperty<Any?, T> {
    private var value: T = initial
    override fun getValue(t: Any?, p: KProperty<*>) = value
    override fun setValue(t: Any?, p: KProperty<*>, v: T) {
        println("Setting ${p.name} = $v"); value = v
    }
}
var x: Int by LoggedDelegate(0)
fun main() { x = 10; x = 20 }

ข้อควรทราบเกี่ยวกับความปลอดภัยระหว่างเธรด

โดยค่าเริ่มต้น ทั้ง observable และ vetoable ไม่ปลอดภัยต่อการทำงานพร้อมกันหลายเธรด สำหรับการเข้าถึงพร้อมกัน ให้ป้องกันการเปลี่ยนแปลงด้วย Mutex หรือจัดการการทำงานให้สอดคล้องกันจากภายนอก

import kotlin.properties.Delegates
// Not thread-safe as-is:
var sharedState: String by Delegates.observable("start") { _, old, new ->
    println("$old -> $new")
}
// In coroutines, wrap access with Mutex if needed

รูปแบบการใช้งานจริง: การตรวจสอบแบบฟอร์ม

ใช้ vetoable แยกสำหรับแต่ละฟิลด์เพื่อการตรวจสอบแบบฟอร์มเชิงประกาศ โดยแต่ละฟิลด์จะตรวจสอบค่าของตนเองเมื่อมีการกำหนดค่า

import kotlin.properties.Delegates
data class Form(
    var username: String = "",
    var password: String = ""
) {
    var validUsername: String by Delegates.vetoable("") { _,_,v -> v.length >= 3 }
    var validPassword: String by Delegates.vetoable("") { _,_,v -> v.length >= 8 }
}
fun main() {
    val f = Form()
    f.validUsername = "ab";       println(f.validUsername) // ""
    f.validUsername = "alice";    println(f.validUsername) // "alice"
    f.validPassword = "short";    println(f.validPassword) // ""
    f.validPassword = "secure123";println(f.validPassword) // "secure123"
}

ตรวจสอบอย่างรวดเร็ว

vetoable เรียกใช้การเรียกกลับเมื่อใด

ทบทวน

observable จะแจ้งเตือนหลังการเปลี่ยนแปลงแต่ละครั้ง ส่วน vetoable จะทำงานก่อนการกำหนดค่าและสามารถปฏิเสธค่าใหม่ได้ ทั้งสองอย่างเหมาะอย่างยิ่งสำหรับการบันทึกข้อมูล การตรวจสอบ และรูปแบบพร็อพเพอร์ตีแบบตอบสนอง โดยไม่ต้องใช้ไลบรารีภายนอก

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

บทเรียน “ตัวแทน observable และ vetoable” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ตัวแทน observable และ vetoable” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Kotlin Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ตัวแทน observable และ vetoable”

ตอบสนองต่อการเปลี่ยนแปลงพร็อพเพอร์ตีด้วย observable และปฏิเสธตามเงื่อนไขด้วย vetoable คุณปฏิบัติ Kotlin Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Kotlin Academy หรือไม่

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

บทเรียน “ตัวแทน observable และ vetoable” ใช้เวลานานแค่ไหน

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

ฉันเขียนและรันโค้ดในบทเรียน Kotlin Academy นี้ได้ไหม

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

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

  1. by lazy: เจาะลึกการเริ่มต้นแบบเลื่อนเวลา
  2. ตัวแทน observable และ vetoable
  3. การเขียนตัวแทน ReadWriteProperty แบบกำหนดเอง
  4. ตัวแทนสำหรับ Preferences พร็อพเพอร์ตีที่ใช้ Map และการบันทึก
← กลับไปที่ Kotlin Academy