Event Bus ونمط Observer في TypeScript: من النظرية إلى التطبيق
\n\nتتطلب تطوير الويب الحديث بنية مرنة وقابلة للتوسع. هناك نمطان رئيسيان يساعدان في تنظيم التفاعل بين المكونات وهما Event Bus و Observer. في هذه المقالة، سنشرح تنفيذهما في TypeScript، والمزايا، وسيناريوهات الاستخدام العملية.
\n\nما هو نمط Observer؟
\n\nنمط Observer (المراقب) هو نمط تصميم سلوكي يحدد علاقة "واحد إلى متعدد" بين الكائنات. عندما يغير كائن واحد (الناشر) حالته، يتم إخطار جميع الكائنات التابعة (المشتركون) وتحديثها تلقائيًا.
\n\nالعناصر الأساسية للنمط:
\n- \n
- Subject (الناشر) — الكائن الذي يتتبع التغييرات ويخطر المشتركين. \n
- Observer (المراقب) — الكائن الذي يشترك في تغييرات الناشر. \n
- Event Bus (ناقل الأحداث) — آلية مركزية تدير الاشتراكات وإرسال الأحداث بين المكونات. \n
تنفيذ Event Bus في TypeScript
\n\nيوفر TypeScript إمكانيات ممتازة للكتابة الصارمة، مما يجعل تنفيذ Event Bus آمنًا وقابلاً للتنبؤ. دعنا نلقي نظرة على التنفيذ الأساسي:
\n\ntype EventHandler<T = any> = (payload: T) => void;\n\nclass EventBus {\n private listeners: Map<string, EventHandler[]> = new Map();\n\n // الاشتراك في حدث\n subscribe<T>(event: string, handler: EventHandler<T>): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, []);\n }\n this.listeners.get(event)!.push(handler);\n }\n\n // إلغاء الاشتراك من حدث\n unsubscribe<T>(event: string, handler: EventHandler<T>): void {\n const handlers = this.listeners.get(event);\n if (handlers) {\n this.listeners.set(\n event,\n handlers.filter(h => h !== handler)\n );\n }\n }\n\n // نشر حدث\n emit<T>(event: string, payload: T): void {\n const handlers = this.listeners.get(event);\n if (handlers) {\n handlers.forEach(handler => handler(payload));\n }\n }\n\n // مسح جميع الاشتراكات\n clear(): void {\n this.listeners.clear();\n }\n}\n\nexport const eventBus = new EventBus();\n\nمثال على الاستخدام مع الأحداث المكتوبة
\n\nلزيادة أمان الكتابة، يمكن تعريف واجهات الأحداث:
\n\n// تعريف أنواع الأحداث\ninterface AppEvents {\n 'user:login': { userId: string; timestamp: number };\n 'user:logout': { userId: string };\n 'data:update': { id: string; data: unknown };\n 'notification:show': { message: string; type: 'success' | 'error' | 'info' };\n}\n\n// إنشاء ناقل مكتوب\nclass TypedEventBus {\n private listeners: Map<string, Function[]> = new Map();\n\n on<K extends keyof AppEvents>(\n event: K,\n handler: (payload: AppEvents[K]) => void\n ): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, []);\n }\n this.listeners.get(event)!.push(handler);\n }\n\n emit<K extends keyof AppEvents>(\n event: K,\n payload: AppEvents[K]\n ): void {\n const handlers = this.listeners.get(event);\n if (handlers) {\n handlers.forEach(handler => handler(payload));\n }\n }\n\n off<K extends keyof AppEvents>(\n event: K,\n handler: (payload: AppEvents[K]) => void\n ): void {\n const handlers = this.listeners.get(event);\n if (handlers) {\n this.listeners.set(\n event,\n handlers.filter(h => h !== handler)\n );\n }\n }\n}\n\nexport const typedBus = new TypedEventBus();\n\nمثال عملي: نظام الإشعارات
\n\nدعنا نلقي نظرة على سيناريو حقيقي — إنشاء نظام إشعارات باستخدام Event Bus: