أنماط التصميم المتقدمة في JavaScript: من النظرية إلى التطبيق
\n\nأنماط التصميم هي حلول مجربة للمشكلات النمطية في تطوير البرمجيات. لمطور JavaScript الذي يعمل مع Node.js، فإن فهم الأنماط المتقدمة يفتح الطريق لإنشاء أنظمة قابلة للتوسع ومرنة وسهلة الصيانة. في هذه المقالة، سنشرح أربعة أنماط رئيسية: Observer، Proxy، Chain of Responsibility و Strategy. سيتم توضيح كل نمط بمثال عملي على Node.js.
\n\n1. نمط Observer (المراقب): الهندسة القائمة على الأحداث في Node.js
\n\nObserver هو أحد الأنماط السلوكية الأساسية. يحدد علاقة "واحد إلى متعدد" بين الكائنات: عندما يغير كائن واحد (الموضوع) حالته، يتم إخطار جميع الكائنات التابعة (المراقبين) وتحديثها تلقائيًا. في Node.js، يشكل هذا النمط أساس وحدة EventEmitter.
مثال: نظام إشعارات لمتجر إلكتروني
\nلنفترض أن لدينا خادمًا يدير الطلبات. عند تغيير حالة الطلب، نحتاج إلى إخطار عدة أنظمة فرعية: التسجيل، إرسال البريد الإلكتروني، وتحديث التحليلات.
\n\nconst EventEmitter = require('events');\n\n// الموضوع (Subject)\nclass OrderManager extends EventEmitter {\n constructor() {\n super();\n this.orders = [];\n }\n\n createOrder(orderId, items) {\n const order = { orderId, items, status: 'created', createdAt: new Date() };\n this.orders.push(order);\n this.emit('order:created', order);\n return order;\n }\n\n updateStatus(orderId, newStatus) {\n const order = this.orders.find(o => o.orderId === orderId);\n if (order) {\n order.status = newStatus;\n this.emit('order:statusChanged', order);\n }\n }\n}\n\n// المراقبون (Observers)\nfunction logObserver(order) {\n console.log(`[LOG] Order ${order.orderId}: status changed to ${order.status} at ${new Date().toISOString()}`);\n}\n\nfunction emailObserver(order) {\n console.log(`[EMAIL] Sending notification for order ${order.orderId} with status ${order.status}`);\n}\n\nfunction analyticsObserver(order) {\n console.log(`[ANALYTICS] Recording event: order ${order.orderId} -> ${order.status}`);\n}\n\n// الاستخدام\nconst manager = new OrderManager();\nmanager.on('order:created', logObserver);\nmanager.on('order:statusChanged', logObserver);\nmanager.on('order:statusChanged', emailObserver);\nmanager.on('order:statusChanged', analyticsObserver);\n\nmanager.createOrder('ORD-001', ['Book', 'Pen']);\nmanager.updateStatus('ORD-001', 'shipped');\n\n\nيتيح هذا الأسلوب إضافة أو إزالة المراقبين دون تغيير كود الموضوع، مما يجعل النظام مرنًا وسهل التوسيع.
\n\n2. نمط Proxy (الوكيل): التحكم في الوصول والتخزين المؤقت
\n\nيوفر Proxy كائنًا بديلًا يدير الوصول إلى كائن آخر. في JavaScript، يتم تنفيذ هذا النمط من خلال الكائن المدمج Proxy، الذي يسمح باعتراض وإعادة تعريف العمليات الأساسية (الوصول إلى الخصائص، استدعاء الدوال، إلخ).
مثال: وكيل تخزين مؤقت لاستعلامات API
\nلنفترض أن لدينا خدمة تقوم باستعلامات مكلفة لواجهة برمجة تطبيقات خارجية. نريد تخزين النتائج مؤقتًا لتجنب الاستدعاءات المتكررة.
\n\n// الخدمة الحقيقية (Real Subject)\nclass ExternalApiService {\n async fetchUser(id) {\n console.log(`Fetching user ${id} from external API...`);\n // محاكاة تأخير الشبكة\n await new Promise(resolve => setTimeout(resolve, 1000));\n return { id, name: `User ${id}`, email: `user${id}@example.com` };\n }\n}\n\n// الوكيل (Proxy)\nclass CachingProxy {\n constructor(realService) {\n this.realService = realService;\n this.cache = new M