حقن التبعية في Swift: دليل شامل للمبتدئين

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

ما هو حقن التبعية في Swift ولماذا تحتاجه؟

\n\n

حقن التبعية (Dependency Injection) أو DI هو أحد المبادئ الأساسية للتصميم في تطوير iOS الحديث. إذا كنت قد بدأت للتو رحلتك مع Swift، فربما واجهت بالفعل موقفًا حيث يقوم أحد الفئات بإنشاء كائنات من فئة أخرى مباشرة داخل نفسه. يُسمى هذا الاقتران المحكم (tight coupling)، وهذا يجعل الكود الخاص بك صعبًا في الاختبار والصيانة.

\n\n

يحل حقن التبعية هذه المشكلة: بدلاً من أن يقوم الفئة بإنشاء تبعياته بنفسه، يتم "حقنها" من الخارج. هذا يجعل الكود أكثر مرونة وقابلية للاختبار ويتوافق مع مبدأ المسؤولية الواحدة (Single Responsibility) من SOLID.

\n\n

في هذه المقالة، سنشرح كيفية عمل حقن التبعية في Swift مع أمثلة عملية، ونوضح كيفية تطبيق هذه الممارسة في مشاريعك لنظامي iOS و macOS.

\n\n

الأنواع الرئيسية لحقن التبعية في Swift

\n\n

هناك ثلاث طرق رئيسية لحقن التبعيات في Swift. يعتمد اختيار الطريقة المحددة على بنية تطبيقك.

\n\n

1. حقن المُنشئ (Constructor Injection)

\n

الطريقة الأكثر شيوعًا والموصى بها. يتم تمرير التبعيات عبر init الخاص بالفئة. هذا يضمن أن الكائن دائمًا في حالة صالحة.

\n\n
// بروتوكول للخدمة\nprotocol DataServiceProtocol {\n    func fetchData() -> String\n}\n\n// التنفيذ الفعلي\nclass DataService: DataServiceProtocol {\n    func fetchData() -> String {\n        return "بيانات من الخادم"\n    }\n}\n\n// الفئة التي تستخدم الخدمة\nclass ViewModel {\n    private let dataService: DataServiceProtocol\n    \n    // يتم حقن التبعية عبر المُنشئ\n    init(dataService: DataServiceProtocol) {\n        self.dataService = dataService\n    }\n    \n    func loadData() {\n        let data = dataService.fetchData()\n        print("تم التحميل: \\(data)")\n    }\n}\n\n// الاستخدام\nlet service = DataService()\nlet viewModel = ViewModel(dataService: service)\nviewModel.loadData()
\n\n

2. حقن الخاصية (Property Injection)

\n

يُستخدم عندما لا تكون التبعية إلزامية لعمل الكائن أو يمكن أن تتغير خلال دورة حياته. من المهم عدم نسيان تعيين الخاصية قبل الاستخدام.

\n\n
class NetworkManager {\n    var urlSession: URLSession?\n    \n    func makeRequest() {\n        guard let session = urlSession else {\n            print("خطأ: الجلسة غير محددة")\n            return\n        }\n        // العمل مع session\n        print("تم تنفيذ الطلب عبر \\(session)")\n    }\n}\n\n// الاستخدام\nlet manager = NetworkManager()\nmanager.urlSession = URLSession.shared  // حقن التبعية\nmanager.makeRequest()
\n\n

3. حقن الطريقة (Method Injection)

\n

مثالي عندما تكون التبعية مطلوبة فقط لتنفيذ طريقة معينة واحدة.

\n\n
class PaymentProcessor {\n    func processPayment(amount: Double, using gateway: PaymentGatewayProtocol) -> Bool {\n        // gateway يُستخدم هنا فقط\n        return gateway.charge(amount: amount)\n    }\n}\n\nprotocol PaymentGatewayProtocol {\n    func charge(amount: Double) -> Bool\n}\n\nclass StripeGateway: PaymentGatewayProtocol {\n    func charge(amount: Double) -> Bool {\n        print("دفع \\(amount) عبر Stripe")\n        return true\n    }\n}\n\n// الاستخدام\nlet processor = PaymentProcessor()\nlet stripe = StripeGateway()\nlet result = processor.processPayment(amount: 99.99, using: stripe)
\n\n

لماذا يجب استخدام حقن التبعية في مشاريع iOS؟

\n\n

يتجاهل العديد من مطوري Swift المبتدئين DI، معتبرين أنه تعقيد غير ضروري. ومع ذلك، في الممارسة العملية، تظهر الفوائد بسرعة كبيرة:

\n\n
    \n
  • تبسيط الاختبار (Unit Testing): يمكنك بسهولة استبدال الخدمات الحقيقية بـ

المدونات

توصيات الكتب