Event Bus ونمط Observer في TypeScript: التنفيذ والأمثلة

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

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

ابدأ الدورة

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
\n\n

تنفيذ Event Bus في TypeScript

\n\n

يوفر TypeScript إمكانيات ممتازة للكتابة الصارمة، مما يجعل تنفيذ Event Bus آمنًا وقابلاً للتنبؤ. دعنا نلقي نظرة على التنفيذ الأساسي:

\n\n
type 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:

توصيات