البرمجة الوظيفية أم البرمجة كائنية التوجه في Swift: ماذا تختار لمشروع iOS؟

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

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

ابدأ الدورة

وجهان لعملة واحدة: المنهج الوظيفي مقابل المنهج كائني التوجه في Swift

\n\n

عندما بدأت البرمجة لنظام iOS، اعتقدت أن البرمجة كائنية التوجه هي الطريق الصحيح الوحيد. الفئات، الوراثة، تعدد الأشكال – كل هذا بدا وكأنه كتاب مقدس للمطور. لكن بعد ذلك اكتشفت البرمجة الوظيفية في Swift، وانقلب عالمي رأساً على عقب. اتضح أنه يمكنك كتابة كود لا يغير الحالة، يسهل اختباره، ويبدو كصيغة رياضية.

\n\n

Swift لغة فريدة من نوعها. إنها متعددة النماذج. هذا يعني أنه يمكنك مزج البرمجة كائنية التوجه والمنهج الوظيفي في مشروع واحد، والاستفادة من أفضل ما في العالمين. لكن كيف لا ترتبك؟ متى تستخدم الفئات، ومتى تستخدم الإغلاقات و map؟ دعنا نفهم ذلك.

\n\n

Swift كائني التوجه: الكلاسيكية التي تعمل

\n\n

البرمجة كائنية التوجه في Swift تُبنى حول الفئات والبروتوكولات والوراثة. هذا نموذج حيث تعيش البيانات والسلوك معاً. تقوم بإنشاء نموذج – على سبيل المثال، "مستخدم" – وهذا الكائن يعرف بنفسه كيف يقدم نفسه، وكيف يغير الاسم، أو يحسب العمر.

\n\n

إليك مثال كلاسيكي في Swift:

\n\n
class User {\n    var name: String\n    var age: Int\n    \n    init(name: String, age: Int) {\n        self.name = name\n        self.age = age\n    }\n    \n    func greet() -> String {\n        return "مرحباً، اسمي \\(name) وعمري \\(age) سنة."\n    }\n    \n    func haveBirthday() {\n        age += 1\n    }\n}\n\nlet user = User(name: "آنا", age: 25)\nuser.haveBirthday()\nprint(user.greet()) // مرحباً، اسمي آنا وعمري 26 سنة.
\n\n

في هذا الكود، نستخدم المنهج كائني التوجه في Swift. لدينا حالة (خصائص name, age) يمكن أن تتغير (طريقة haveBirthday). هذا بديهي، خاصة إذا كنت قادماً من Java أو C++. لكن هناك فارق بسيط: الحالة القابلة للتغيير هي مصدر الأخطاء. كلما زاد عدد الكائنات التي تغير بعضها البعض، زادت صعوبة تصحيح البرنامج.

\n\n

Swift الوظيفي: قوة الإغلاقات وعدم القابلية للتغيير

\n\n

البرمجة الوظيفية في Swift تقدم نظرة مختلفة. هنا، الدوال هي "مواطنون من الدرجة الأولى". يمكنك تمريرها كمعاملات، وإرجاعها من دوال أخرى، وتخزينها في متغيرات. المبدأ الرئيسي هو الدوال النقية التي لا تغير الحالة الخارجية وتعيد دائماً نفس النتيجة لنفس المدخلات.

\n\n

لنرى كيف يبدو نفس المثال بالأسلوب الوظيفي:

\n\n
struct User {\n    let name: String\n    let age: Int\n}\n\nfunc greet(user: User) -> String {\n    return "مرحباً، اسمي \\(user.name) وعمري \\(user.age) سنة."\n}\n\nfunc haveBirthday(user: User) -> User {\n    return User(name: user.name, age: user.age + 1)\n}\n\nlet user = User(name: "آنا", age: 25)\nlet olderUser = haveBirthday(user: user)\nprint(greet(user: olderUser)) // مرحباً، اسمي آنا وعمري 26 سنة.
\n\n

لاحظ: نحن نستخدم هيكلاً (struct) وليس فئة. الهياكل في Swift هي أنواع قيمة. يتم نسخها عند التعيين. الدالة haveBirthday لا تغير الكائن الأصلي، بل تنشئ كائناً جديداً. هذه هي الفكرة الأساسية لـ المنهج الوظيفي – عدم القابلية للتغيير.

\n\n

مقارنة المنهجين: متى نستخدم أياً منهما؟

\n\n

الآن دعنا نقارن بصراحة بين البرمجة كائنية التوجه والبرمجة الوظيفية في Swift. لكل منهما نقاط قوته.

\n\n

المنهج كائني التوجه في Swift

\n\n
    \n
  • الإيجابيات: بديهي لنمذجة العالم الحقيقي. مناسب تماماً لمكونات واجهة المستخدم (UIViewController, UIView). الوراثة تبسط إعادة استخدام الكود.
  • \n
  • السلبيات: قابلية التغيير
  • \n

المدونات

توصيات الكتب