هندسة Event-driven باستخدام TypeScript: كتابة كود مرن يعتمد على الأحداث

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

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

ابدأ الدورة

هندسة Event-driven باستخدام TypeScript: عندما "يسمع" الكود بعضه البعض

\n\n

تخيل أنك تكتب تطبيق ويب معقد: برنامج مراسلة، بوت تداول، أو نظام مراقبة خوادم. في مرحلة ما، تدرك أن مجرد استدعاء الدوال في سلسلة هو جحيم. وحدة واحدة تسحب أخرى، والثالثة مرتبطة بالرابعة، وعند تغيير المنطق ينهار كل شيء مثل بيت من ورق.

\n\n

هل هذا مألوف؟ إذن أنت بحاجة إلى هندسة Event-driven باستخدام TypeScript. هذا ليس مجرد مصطلح عصري، بل طريقة حقيقية لجعل الكود مرنًا وقابلاً للتوسع وواضحًا. في هذه المقالة، سنشرح كيف تعمل البرمجة الموجهة بالأحداث، ونكتب ناقل الأحداث الخاص بنا باستخدام TypeScript، ونرى أين يكون هذا مفيدًا حقًا.

\n\n

ما هي هندسة Event-driven بكلمات بسيطة

\n\n

هندسة Event-driven (الهندسة الموجهة بالأحداث) هي نهج تتواصل فيه مكونات النظام عبر الأحداث. وحدة واحدة تولد حدثًا (مثل "قام المستخدم بالتسجيل")، وتشترك وحدات أخرى فيه وتستجيب له. لا ترتبط هذه الوحدات ببعضها البعض بشكل مباشر.

\n\n

يبدو هذا مجردًا؟ دعنا نأخذ مثالاً من الحياة الواقعية. تخيل مكتبًا:

\n
    \n
  • النهج التقليدي: المدير يذهب شخصيًا إلى كل موظف ويقول: "أعد التقرير".
  • \n
  • Event-driven: المدير يصرخ: "التقرير مطلوب!" - وكل من يعرف كيفية إعداده يبدأ العمل بنفسه.
  • \n
\n\n

في الحالة الثانية، لا يحتاج المدير إلى معرفة من سيقوم بإعداد التقرير بالضبط. هو فقط يرسل الحدث. ويمكن للموظفين الانضمام والانسحاب دون تغيير منطق المدير. هذا هو جوهر البرمجة الموجهة بالأحداث.

\n\n

لماذا يعتبر TypeScript مثاليًا للهندسة القائمة على الأحداث

\n\n

JavaScript بحد ذاته موجه بالأحداث (تذكر addEventListener)، ولكن في المشاريع الكبيرة بدون أنواع يبدأ الفوضى. أحداث TypeScript تحل هذه المشكلة: أنت تعرف بالضبط البيانات التي تأتي مع الحدث، وسيقوم المترجم بالتقاط الخطأ في مرحلة التطوير وليس في وقت التشغيل.

\n\n

بالإضافة إلى ذلك، يدعم TypeScript الأدوية العامة (Generics)، والتحميل الزائد (Overloads)، والكتابة الصارمة لدوال الاسترجاع (Callbacks) - كل ما هو مطلوب لإنشاء ناقل أحداث موثوق.

\n\n

كتابة Event Bus باستخدام TypeScript من الصفر

\n\n

لنبدأ بمثال بسيط ولكنه عملي. سننشئ كلاس EventBus - ناقل أحداث مركزي تتواصل من خلاله جميع الوحدات.

\n\n
// event-bus.ts\ntype EventHandler<T = any> = (data: T) => void;\n\nclass EventBus {\n  private handlers: Map<string, EventHandler[]> = new Map();\n\n  // الاشتراك في الحدث\n  on<T>(event: string, handler: EventHandler<T>): void {\n    if (!this.handlers.has(event)) {\n      this.handlers.set(event, []);\n    }\n    this.handlers.get(event)!.push(handler as EventHandler);\n  }\n\n  // إلغاء الاشتراك من الحدث\n  off(event: string, handler: EventHandler): void {\n    const handlers = this.handlers.get(event);\n    if (handlers) {\n      this.handlers.set(event, handlers.filter(h => h !== handler));\n    }\n  }\n\n  // إصدار الحدث\n  emit<T>(event: string, data: T): void {\n    const handlers = this.handlers.get(event);\n    if (handlers) {\n      handlers.forEach(handler => handler(data));\n    }\n  }\n}\n\nexport const globalEventBus = new EventBus();
\n\n

هكذا قمنا بكتابة هندسة Event-driven بسيطة باستخدام TypeScript. الآن يمكن لأي وحدة استيراد globalEventBus وإما الاستماع إلى الأحداث أو توليدها.

\n\n

مثال على الاستخدام: الإشعارات وتسجيل الأحداث

\n\n

لنفترض أن لدينا وحدة مصادقة ووحدة إشعارات. لا ينبغي لهما معرفة بعضهما البعض بشكل مباشر.

\n\n
// auth-module.ts\nimport { globalEventBus } from './event-bus';\n\nexport function loginUser(email: string): void {\n  // ... منطق تسجيل الدخول\n  console.log(`المستخدم                

المدونات

توصيات الكتب