HandsAppMVP: بنية iOS للاستعانة بمصادر خارجية لتطوير الاستوديو

صورة

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

صورة

في تطوير نظام iOS ، تحدد الهندسة بشكل أساسي تنظيم الطبقات والتبعيات لمستخدم واحد محدد ViewController. ومع ذلك ، يمكن أن يكون العنصر المركزي ليس هو فقط ، ولكن ببساطة UIView. يعتمد الاختيار على المهمة المحددة.

مقارنة العمارة


هناك العديد من القوالب المعمارية القياسية لنظام iOS: MVC و MVP و MVVM و VIPER (يمكن العثور على روابط لوصف كل منها في نهاية المقالة).

باختيار بنية للتطوير ، حددنا المعلمات الرئيسية التي يجب أن تتوافق مع: سرعة التطوير والمرونة وعتبة الدخول المنخفضة. بعد ذلك ، بدأنا بمقارنة ثلاث بنيات معروفة مع هذه المعلمات في الاعتبار (تم دفن نموذج مجتمع MVC iOS منذ فترة طويلة بسبب عدم الامتثال الصارم لمسؤولية واحدة).

بالنسبة لفريق الاستعانة بمصادر خارجية ، تعد سرعة التطوير مهمة بشكل خاص. تعتبر VIPER هي العمارة الأكثر تعقيدًا و "بطيئة" ؛ فالتطوير أسرع باستخدام MVP أو MVVM النقي ، نظرًا لأنها تحتوي على مكونات أقل.

المرونة تعني إضافة أو إزالة الوظائف في التطبيق دون ألم. ترتبط هذه المعلمة ارتباطًا وثيقًا بسرعة التطوير في جميع مراحل عمر التطبيق ، باستثناء المرحلة الأولى. ترتبط المرونة أيضًا ارتباطًا وثيقًا ببساطة الاختبار - الاختبارات التلقائية تمنح المطور الثقة بأنه لن يكسر أي شيء ، ويساعد على تجنب الأخطاء. تغطية MVP الكلاسيكية ضعيفة بالاختبارات ، خاصة إذا كنت لا تستخدم واجهات الفصل الموضحة أدناه. أداء MVVM من وجهة نظر الاختبار ضعيف أيضًا ، لأن اختبار الكود التفاعلي يستغرق وقتًا أطول. تعتبر VIPER رائعة لكتابة الاختبارات لأنها تحترم مبدأ المسؤولية الفردية قدر الإمكان وتعتمد الطبقات على التجريد.

والمعلمة الأخيرة التي أخذناها بعين الاعتبار هي عتبة الإدخال. يظهر مدى سرعة اختراق المطورين الجدد (أولاً وقبل كل شيء ، jones) في الهندسة المعمارية. هنا MVVM باستخدام المكتبات التفاعلية من طرف ثالث (RxSwift ، PromiseKit ، إلخ.) تحتل المرتبة الأخيرة المشرفة لأسباب واضحة. VIPER هي أيضًا بنية معقدة إلى حد ما بسبب العدد الكبير من المكونات. MVP لديه أدنى عتبة دخول.

بعد تقييم الإيجابيات والسلبيات ، توصلنا إلى استنتاج مفاده أننا بحاجة إلى شيء بسيط مثل MVP ومرونة مثل VIPER. لذلك ولدت الفكرة لإنشاء الهندسة المعمارية الخاصة بهم بناءً على - HandsAppMVP.

قم بتوسيع MVP


المكونات الرئيسية لبنيتنا هي Model، View، Presenter. إنهم يؤدون نفس الوظائف كما في MVP الكلاسيكي وفقًا للمخطط المعروف جيدًا:

صورة
[مخطط MVP الكلاسيكي]

هنا وأدناه ، كل مكون تفاعل (مربع أزرق) في الرسوم البيانية هو فئة تتزامن حياتها مع عمر العرض. يشير السهم الصلب إلى ملكية كائن آخر ورابط قوي وسهم منقط يشير إلى ارتباط ضعيف. بمراجع ضعيفة ، نمنع التبعيات الدائرية وتسرب الذاكرة.

واجهات


أولاً ، أضفنا واجهات ViewInput و ViewOutput إلى هذا المخطط الكلاسيكي. أخذنا في الاعتبار المبدأ الخامس من SOLID - مبدأ انعكاس التبعية. من المرجح أنه ليس إضافة ، بل صقل لـ MVP. يساعد الاعتماد على التجريد على التخلص من الترابط الصارم للمكونات ويسمح لك بكتابة الاختبارات بشكل طبيعي. يبدو المخطط مع مراعاة الواجهات كما يلي:

صورة
[إضافة واجهات ViewInput و ViewOutput]

المستطيل الصغير هو واجهة.

سوف يسأل المطور اليقظ ، أين هي واجهات Model؟ الآن ننتقل إليهم.

العمل مع البيانات


نموذج البيانات في معماريات الهاتف النقال هو مفهوم جماعي. مثال قياسي: يقرع تطبيق على الشبكة للتفاعل مع الخادم ، ثم يحفظ البيانات في CoreData للعمل دون اتصال ، ويكتب بعض المعلومات البسيطة إلى UserDefaults ويخزن JWT في Keychain. كل هذه البيانات التي يتم التفاعل معها تشكل النموذج.

الفئة المسؤولة عن التفاعل مع حاوية البيانات من نوع معين ، نسمي خدمة البيانات. لكل حاوية (قاعدة بيانات بعيدة ، قاعدة بيانات محلية ، UserDefaults ، وما إلى ذلك) ، تتم إضافة فئة خدمة إلى HandsAppMVP التي تتفاعل مع مقدم العرض. يمكنك الآن أيضًا إضافة واجهات إدخال / إخراج لكل خدمة بيانات:

صورة
[إضافة خدمات للعمل مع البيانات]

لا يلزم توصيل كل فئة خدمة بالمقدم باستخدام واجهة ، على سبيل المثال ، عند استخدام Moya. مويا هي مكتبة شبكة مفتوحة المصدر. توفر Moya فئة خدمة جاهزة (MoyaProvider) ، وعند كتابة الاختبارات ، لا يتعين علينا إنشاء كائن وهمي يحل محل ApiProvider. يوفر Moya وضع اختبار خاص ، عند تشغيله ، لا يطرق MoyaProvider على الشبكة ، ولكنه يعيد بيانات الاختبار (يمكن العثور على مزيد من التفاصيل هنا). في هذه الحالة ، لا يشير المقدم إلى تجريد MoyaProvider ، بل إلى التنفيذ. ونحصل على تعليقات من هذه الخدمة باستخدام عمليات الإغلاق. يمكن العثور على تنفيذ مثال في المشروع التجريبي.

هذا المثال هو استثناء أكثر من قاعدة ، ويظهر أن الالتزام بـ SOLID ليس دائمًا أفضل حل.

التنقل


نعتبر التنقل في التطبيق مسؤولية منفصلة. يستخدم HandsAppMVP فئة خاصة لذلك - جهاز التوجيه. يحتوي جهاز التوجيه على ارتباط ضعيف للعرض ، والذي يمكنه من خلاله إظهار شاشة جديدة أو إغلاق الشاشة الحالية. يتفاعل جهاز التوجيه أيضًا مع مقدم العرض باستخدام واجهة RouterInput:

صورة
[إضافة مكون للتنقل (جهاز التوجيه)]

تجميع المكونات


الإضافة الأخيرة إلى MVP الكلاسيكية التي نستخدمها هي Assembly ، فئة تجميع. يتم استخدامه لتهيئة العرض والمكونات الأخرى لـ HandsAppMVP ، وكذلك لتنفيذ التبعيات. يحتوي التجميع على الطريقة العامة الوحيدة - `التجمع () -> UIViewController ، والنتيجة هي UIViewController (أو UIView) مع الرسم البياني للتبعية اللازمة.

لن نعرض التجميع على الرسم التخطيطي للهندسة المعمارية ، لأنه غير متصل بمكونات MVP وتنتهي دورة حياتها فور إنشائها.

رمز الجيل


لتوفير الوقت ، قمنا بأتمتة عملية إنشاء فئات HandsAppMVP باستخدام Generamba. يمكن العثور على القوالب المستخدمة لـ Generamba في مستودعنا. يوجد مثال لتكوين Generamba في المشروع التجريبي.

نتيجة لإنشاء شاشة محددة ، نحصل على مجموعة من الفئات التي تتوافق مع مخطط HandsAppMVP ، ومجموعة من اختبارات الوحدة لإنشاء المكونات وتنفيذها ، وكذلك فئة قالب لاختبارات مقدم العرض.

ماذا حدث


إذا قارنت HandsAppMVP و VIPER بين الرأسين ، فستلاحظ أنهما متشابهان جدًا ، ولا يتم تمييز الأول إلا بغياب مكون Interactor. ولكن ، التخلص من الطبقة بين الخدمات والحاضر (المتفاعل) ، وكذلك تبسيط التفاعل مع الشبكة باستخدام Moya ، تلقينا زيادة ملحوظة في سرعة التطوير.

ننصحك بإيلاء اهتمام كاف للهندسة المعمارية في مرحلة التصميم من أجل تجنب الأخطاء العالمية ، والنزاعات مع العملاء وعذاب المطورين في المستقبل ، وبدلاً من ذلك قيادة عملية التطوير بكفاءة وتوقع.

تذكر أن أي بنية قد لا تكون مناسبة بشكل خاص لمشروعك ، لذلك لا تتسرع في التمسك بشكل أعمى بالقوالب الجاهزة والقصص الناجحة لتطبيقها. لا تخف من تطوير حلولك وتطبيقها - يمكن أن تصبح أكثر قيمة ومرونة بالنسبة لك من الحلول الجاهزة.

في الختام ، نوصي ببعض المقالات الجيدة حول بنية تطبيقات iOS التي ساعدتنا على فهم التعقيدات وتحديد خيارنا:

  1. الأنماط المعمارية في iOS
  2. iOS Swift: معمارية MVP
  3. تحليل بنية VIPER على سبيل المثال من تطبيق iOS صغير على Swift 4
  4. تنفيذ MVVM على iOS مع RxSwift

كما كانت وثائق SurfStudio مفتوحة المصدر مفيدة جدًا ومستوحاة .

أخيرًا ، نحن نضع رابطًا حول مشروع DEMO ، مكتوبًا في HandsAppMVP ، والذي ذكرناه مرارًا وتكرارًا في المقالة.

All Articles