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

รูปแบบตัวห่อหุ้มที่ใช้บ่อย (การตรวจสอบความถูกต้อง การแคช)

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

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

สิ่งที่จะสร้าง

บทเรียนนี้แสดงรูปแบบการใช้งานจริงสองแบบ:

  • การตรวจสอบความถูกต้อง: รับข้อมูลเข้าหรือแก้ไขข้อมูลเข้าด้วยค่าเริ่มต้นและข้อความ
  • การแคช: จัดเก็บผลลัพธ์ และเปิดเผย ตัวช่วย เช่น clear() และ isCached

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

@NonEmpty ป้องกันข้อมูลเข้าที่ว่างเปล่าและจัดหาค่าเริ่มต้นให้ ส่วน ค่าที่ฉาย จะรายงานว่าค่าที่กำหนดครั้งล่าสุดถูกแก้ไขโดยอัตโนมัติหรือไม่

@propertyWrapper
struct NonEmpty {
    private var value: String = ""
    private(set) var lastFixed: Bool = false

    var wrappedValue: String {
        get { value }
        set {
            if newValue.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
                value = "N/A"          // default fallback
                lastFixed = true
            } else {
                value = newValue
                lastFixed = false
            }
        }
    }

    var projectedValue: Bool { lastFixed } // $name -> was fixed?

    init(wrappedValue: String) { self.wrappedValue = wrappedValue }
}

struct Profile {
    @NonEmpty var displayName: String = "  "
}
var p = Profile()
print(p.displayName)  // "N/A"
print(p.$displayName) // true (was fixed)

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

@Validated เป็นแบบทั่วไปและรับคลอเชอร์ กฎ พร้อมกับ ค่าสำรอง ใช้สำหรับตรวจสอบความยาว ช่วง หรือเงื่อนไขแบบกำหนดเอง

@propertyWrapper
struct Validated<Value> {
    private var value: Value
    private let rule: (Value) -> Bool
    private let fallback: Value
    private(set) var lastValid: Bool = true

    var wrappedValue: Value {
        get { value }
        set {
            if rule(newValue) {
                value = newValue
                lastValid = true
            } else {
                value = fallback
                lastValid = false
            }
        }
    }

    var projectedValue: Bool { lastValid } // $prop -> is valid?

    init(wrappedValue: Value, rule: @escaping (Value) -> Bool, fallback: Value) {
        self.rule = rule
        self.fallback = fallback
        self.value = wrappedValue
        self.lastValid = rule(wrappedValue)
        if !lastValid { self.value = fallback }
    }
}

struct Form {
    @Validated(rule: { $0.count >= 3 }, fallback: "???")
    var nickname: String = "hi"
}
var f = Form()
print(f.nickname)   // "???" (invalid -> fallback)
print(f.$nickname)  // false

การแคช: การจดจำค่าแบบเลื่อนเวลา

@LazyCached จะจดจำค่าจากคลอเชอร์ $result เปิดเผยตัวช่วย isCached และ clear()

@propertyWrapper
struct LazyCached<Value> {
    private var storage: Value?
    private let build: () -> Value

    var wrappedValue: Value {
        mutating get {
            if let v = storage { return v }         // hit
            let v = build()                         // miss -> compute
            storage = v
            return v
        }
        // Optional: allow manual set to override cache
        set { storage = newValue }
    }

    struct Controls {
        private let getter: () -> Bool
        private let clearer: () -> Void
        var isCached: Bool { getter() }
        func clear() { clearer() }
    }

    var projectedValue: Controls {
        Controls(
            getter: { self.storage != nil },
            clearer: { self.storage = nil }
        )
    }

    init(_ build: @escaping () -> Value) {
        self.build = build
        self.storage = nil
    }
}

// Demo: expensive computation (simulated)
var calls = 0
func heavy() -> Int { calls += 1; return (1...10_000).reduce(0, +) }

struct Engine {
    @LazyCached(heavy) var result: Int
}
var e = Engine()
print(e.$result.isCached) // false
print(e.result)           // computes once
print(e.result)           // uses cache
print(calls)              // 1

การแคชตาม TTL

@TimedCache จะรีเฟรชหลังครบ TTL ค่าที่ฉายอาจเปิดเผย age เพื่อให้จุดเรียกใช้งานตัดสินใจได้ว่าจะรีเฟรชเมื่อใด

@propertyWrapper
struct TimedCache<Value> {
    private var storage: Value?
    private var timestamp: Date?
    private let ttl: TimeInterval
    private let build: () -> Value

    var wrappedValue: Value {
        mutating get {
            let now = Date()
            if let t = timestamp, let v = storage, now.timeIntervalSince(t) < ttl {
                return v                              // fresh
            }
            let v = build()                           // refresh
            storage = v
            timestamp = now
            return v
        }
    }

    struct Status { let age: TimeInterval? }
    var projectedValue: Status {
        let age = timestamp.map { Date().timeIntervalSince($0) }
        return Status(age: age)
    }

    init(ttl: TimeInterval, _ build: @escaping () -> Value) {
        self.ttl = ttl
        self.build = build
    }
}

// Demo (age only; TTL behavior depends on real time)
struct Stats {
    @TimedCache(ttl: 60) { Int.random(in: 0...1000) } var score: Int
}
var s2 = Stats()
print(s2.score)         // computes
print(s2.$score.age ?? -1)

แนวทางการออกแบบ

เคล็ดลับการออกแบบ:

  • ให้การตรวจสอบความถูกต้อง ไม่มีผลข้างเคียงและคาดเดาได้ รายงานการแก้ไขผ่าน ธงสถานะ
  • สำหรับการแคช ให้เก็บสถานะไว้ให้น้อย และจัดเตรียม clear() หรือ isCached
  • ควรใช้ อาร์กิวเมนต์ตอนสร้าง สำหรับนโยบายต่าง ๆ เช่น ค่าสำรองและ TTL

ตัวช่วยที่ฉายค่าสำหรับการแคช

ตรวจสอบอย่างรวดเร็ว: $value ควรเปิดเผยอะไรในตัวห่อหุ้มสำหรับการแคช

สรุปทบทวน

สรุปทบทวน: ใช้ตัวห่อหุ้มเพื่อตรวจสอบความถูกต้องของข้อมูลเข้า (ค่าเริ่มต้นและกฎ) และเพื่อแคชผลลัพธ์ที่ใช้เวลาประมวลผลมาก (แบบเลื่อนเวลาและ TTL) จัดเก็บการควบคุมและสถานะไว้ใน ค่าที่ฉาย เพื่อให้จุดเรียกใช้งานสะอาดและชัดเจน

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

บทเรียน “รูปแบบตัวห่อหุ้มที่ใช้บ่อย (การตรวจสอบความถูกต้อง การแคช)” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “รูปแบบตัวห่อหุ้มที่ใช้บ่อย (การตรวจสอบความถูกต้อง การแคช)”

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

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

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

บทเรียน “รูปแบบตัวห่อหุ้มที่ใช้บ่อย (การตรวจสอบความถูกต้อง การแคช)” ใช้เวลานานแค่ไหน

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

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

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

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

  1. การสร้างตัวห่อหุ้มและ projectedValue
  2. การนำกลับมาใช้ใหม่และข้อจำกัด
  3. รูปแบบตัวห่อหุ้มที่ใช้บ่อย (การตรวจสอบความถูกต้อง การแคช)
← กลับไปที่ Swift Academy