Event Bus ونمط Observer في Kotlin: دليل شامل
\n\nفي تطوير التطبيقات الحديثة بلغة Kotlin (خاصة لنظام Android)، غالبًا ما تنشأ الحاجة إلى تنظيم تفاعل ضعيف الاقتران بين المكونات. يوفر نمط Observer وتطبيقه العملي - Event Bus - حلاً أنيقًا لهذه المشكلة. في هذه المقالة، سنشرح بالتفصيل ما هو Event Bus، وكيف يعمل نمط Observer، وكيفية تطبيق هذه المفاهيم في مشاريع Kotlin.
\n\nما هو نمط Observer؟
\n\nنمط Observer (المراقب) هو نمط تصميم سلوكي، حيث يقوم كائن واحد (الموضوع) بإعلام مجموعة من الكائنات الأخرى (المراقبين) بالتغييرات في حالته. المكونات الأساسية:
\n\n- \n
- Subject — ناشر الأحداث، الذي يحتفظ بقائمة المشتركين. \n
- Observer — المشترك، الذي يتلقى الإشعارات. \n
- Event — رسالة أو بيانات محددة يتم نقلها من الناشر إلى المشتركين. \n
Event Bus كتطبيق لنمط Observer
\n\nEvent Bus (ناقل الأحداث) هو آلية مركزية تعمل على تبسيط استخدام نمط Observer. بدلاً من أن يقوم كل موضوع بإدارة قائمة المراقبين يدويًا، يتولى Event Bus جميع منطق الاشتراك وإلغاء الاشتراك وتوصيل الأحداث. هذا مفيد بشكل خاص في التطبيقات ذات البنية المعقدة، حيث لا يجب أن تعرف المكونات بعضها البعض بشكل مباشر.
\n\nمزايا Event Bus في Kotlin
\n\n- \n
- اقتران ضعيف — تتواصل المكونات عبر الناقل دون وجود مراجع مباشرة لبعضها البعض. \n
- تبسيط الاختبار — يمكن محاكاة ناقل الأحداث بسهولة. \n
- المرونة — سهولة إضافة مشتركين جدد دون تغيير الكود الموجود. \n
- عدم التزامن — يمكن معالجة الأحداث في سلاسل تنفيذ مختلفة. \n
تنفيذ بسيط لـ Event Bus في Kotlin
\n\nلنقم بإنشاء تنفيذ بسيط خاص بنا لـ Event Bus دون استخدام مكتبات خارجية. سيساعدنا هذا على فهم الآلية الداخلية للعمل.
\n\nimport kotlin.reflect.KClass\n\nclass EventBus {\n private val subscribers = mutableMapOf<KClass<*>, MutableList<(Any) -> Unit>>()\n\n // الاشتراك في حدث من نوع معين\n inline fun <reified T : Any> subscribe(crossinline onEvent: (T) -> Unit) {\n val eventType = T::class\n subscribers.getOrPut(eventType) { mutableListOf() }.add { event ->\n if (event is T) {\n onEvent(event)\n }\n }\n }\n\n // إلغاء الاشتراك من جميع الأحداث (للغرض التوضيحي)\n fun <T : Any> unsubscribe(eventType: KClass<T>) {\n subscribers.remove(eventType)\n }\n\n // نشر حدث\n fun publish(event: Any) {\n val eventType = event::class\n subscribers[eventType]?.forEach { handler ->\n handler(event)\n }\n }\n}\n\n// مثال على الاستخدام\ndata class UserLoggedIn(val userId: String, val timestamp: Long)\ndata class DataLoaded(val data: String)\n\nfun main() {\n val bus = EventBus()\n\n // الاشتراك في حدث تسجيل دخول المستخدم\n bus.subscribe<UserLoggedIn> { event ->\n println("المستخدم ${event.userId} قام بتسجيل الدخول في ${event.timestamp}")\n }\n\n // الاشتراك في حدث تحميل البيانات\n bus.subscribe<DataLoaded> { event ->\n println("تم تحميل البيانات: ${event.data}")\n }\n\n // نشر الأحداث\n bus.publish(UserLoggedIn("user123", System.currentTimeMillis()))\n bus.publish(DataLoaded("بيانات مثال"))\n}\n\nمكتبة جاهزة: GreenRobot EventBus
\n\nفي المشاريع الحقيقية، غالبًا ما يتم استخدام المكتبات الجاهزة. واحدة من أشهرها لـ Kotlin/Android هي GreenRobot EventBus. وهي محسّنة للعمل مع مكونات Android وتدعم: