Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

التحكم في الوصول

جزء من قسم البرمجة كائنية التوجه في رحلة Swift على Coddy. الدرس 17 من 57.

التغليف يعني أن النوع يتحكم في كيفية استخدام بياناته. يحدد التحكم في الوصول من يمكنه رؤية خاصية أو طريقة. يؤدي وضع وسم private على عضو إلى إخفائه عن جميع التعليمات البرمجية الموجودة خارج النوع (وعن امتداداته في الملف نفسه):

struct Account {
    private var balance = 0

    mutating func deposit(_ amount: Int) {
        balance += amount
    }
}

var a = Account()
a.deposit(50)
// a.balance = 1_000_000   // خطأ: 'balance' غير قابل للوصول بسبب مستوى الحماية 'private'

لا يمكن للكود الخارجي بعد ذلك استخدام سوى ما يقدّمه النوع. ويمكن للنوع التحقق من كل تغيير، لذلك لا تنتهي بياناته أبدًا إلى حالة لا يسمح بها النوع:

struct Account {
    private var balance = 0

    mutating func deposit(_ amount: Int) {
        if amount > 0 { balance += amount }
    }

    func report() -> String {
        "balance: \(balance)"
    }
}

var a = Account()
a.deposit(50)
a.deposit(-999)
print(a.report())

الناتج:

balance: 50

لدى Swift خمسة مستويات للوصول. من دون كلمة مفتاحية، يكون العضو internal: مرئيًا في كل مكان ضمن الوحدة نفسها (تطبيقك أو حزمتك). المستويات من الأكثر انفتاحًا إلى الأكثر تقييدًا:

open        // يمكن للوحدات الأخرى استخدامه وإنشاء فئات فرعية منه (الفئات فقط)
public      // يمكن للوحدات الأخرى استخدامه
internal    // الافتراضي: الوحدة بأكملها
fileprivate // ملف المصدر هذا فقط
private     // هذا النوع (وامتداداته في الملف)

تحافظ أساليب المساعدة الخاصة على صِغر الواجهة العامة: إذ يرى المستدعون ما يفعله النوع، لا كيف يفعله.

struct Password {
    private let text: String

    init(_ text: String) { self.text = text }

    var isStrong: Bool {
        hasDigit() && text.count >= 8
    }

    private func hasDigit() -> Bool {
        text.contains { $0.isNumber }
    }
}

print(Password("secret123").isStrong)
print(Password("short1").isStrong)

الناتج:

true
false
challenge icon

التحدي

سهل

أكمل البنية Locker. إنّ code وitems خاصّتان private. تضيف store(_:code:) عنصرًا فقط عندما يتطابق الرمز، وتُرجع ما إذا كانت قد فعلت ذلك؛ وتُرجع items(code:) العناصر المخزّنة مفصولةً بـ , (أو empty) عندما يتطابق الرمز، وwrong code بخلاف ذلك.

يقرأ الكود المُ supplied رمز الخزانة، ثم يتعامل مع الأوامر put <code> <item> أو open <code>. ويطبع stored أو denied لكل أمر put، والنتيجة لكل أمر open.

ضع كودك في Locker.swift. يحتوي main.swift على كود الإدخال/الإخراج المُ supplied ولا يمكن تعديله.

جرّب بنفسك

// كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
var input: [String] = []
while let line = readLine() { input.append(line) }
var locker = Locker(code: input[0])
for cmd in input.dropFirst() {
    let p = cmd.split(separator: " ").map(String.init)
    if p[0] == "put" {
        print(locker.store(p[2], code: p[1]) ? "stored" : "denied")
    } else {
        print(locker.items(code: p[1]))
    }
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: Playground لـ Swift