0Pricing
Swift Academy · درس

أنماط الأغلفة الشائعة (التحقق والتخزين المؤقت)

أنشئ أغلفة شائعة لـ التحقق و التخزين المؤقت : تحقّق من المدخلات، ووفّر قيمًا افتراضية، واحفظ نتائج العمليات المكلفة مؤقتًا، وأظهر مؤشرات مساعدة عبر القيم المُسقطة.

أنماط الأغلفة الشائعة (التحقق والتخزين المؤقت) درس مجاني في Swift Academy على CoddyKit. هذا هو الدرس 3 من أصل 3. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Swift Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Swift Academy 3 دروس في المجموع.

ما سنبنيه

يعرض هذا الدرس نمطين عمليين:

  • التحقق: قبول المدخلات أو إصلاحها باستخدام قيم افتراضية ورسائل.
  • التخزين المؤقت: تخزين النتائج، وإتاحة $helpers مثل clear() وisCached.

التحقق: NonEmpty

يحمي @NonEmpty من الإدخال الفارغ ويوفّر قيمة افتراضية. ويُظهر projectedValue ما إذا كانت آخر قيمة معيّنة قد أُصلحت تلقائيًا.

@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 عامًا ويقبل إغلاقًا باسم rule بالإضافة إلى قيمة fallback. استخدمه للتحقق من الطول أو النطاق أو الشروط المخصّصة.

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

إرشادات التصميم

نصائح التصميم:

  • اجعل التحقق نقيًا وقابلًا للتوقّع، وأبلغ عن الإصلاحات باستخدام $flags.
  • في التخزين المؤقت، أبقِ الحالة صغيرة، ووفّر clear() أو isCached.
  • فضّل وسائط init لتحديد السياسات، مثل fallback وTTL.

المساعدات المسقطة للتخزين المؤقت

تحقق سريع: ما الذي ينبغي أن تعرضه $value في غلاف للتخزين المؤقت؟

خلاصة

الخلاصة: استخدم الأغلفة من أجل التحقق من المدخلات، باستخدام القيم الافتراضية والقواعد، ومن أجل تخزين النتائج المكلفة مؤقتًا، سواءً بطريقة كسولة أو باستخدام TTL. ضع عناصر التحكم والحالة في projectedValue للحفاظ على بساطة مواضع الاستدعاء.

الأسئلة الشائعة

هل درس «أنماط الأغلفة الشائعة (التحقق والتخزين المؤقت)» مجاني؟

نعم — نص درس «أنماط الأغلفة الشائعة (التحقق والتخزين المؤقت)» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Swift Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Swift Academy 3 دروس في المجموع.

ماذا ستتعلم في «أنماط الأغلفة الشائعة (التحقق والتخزين المؤقت)»؟

أنشئ أغلفة شائعة لـ التحقق و التخزين المؤقت : تحقّق من المدخلات، ووفّر قيمًا افتراضية، واحفظ نتائج العمليات المكلفة مؤقتًا، وأظهر مؤشرات مساعدة عبر القيم المُسقطة. تتمرن على Swift Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Swift Academy؟

لا تُشترط خبرة سابقة. Swift Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 3.

كم من الوقت يستغرق درس «أنماط الأغلفة الشائعة (التحقق والتخزين المؤقت)»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Swift Academy هذا؟

نعم. كل درس في Swift Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. إنشاء الأغلفة و projectedValue
  2. قابلية إعادة الاستخدام والقيود
  3. أنماط الأغلفة الشائعة (التحقق والتخزين المؤقت)
← العودة إلى Swift Academy