جافا سكريبت والسادة: لماذا تحتاج إلى أنماط التصميم (وكيف ستُبسّط حياتك)

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

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

ابدأ الدورة

جافا سكريبت والسادة: لماذا تحتاج إلى أنماط التصميم (وكيف ستُبسّط حياتك)

\n\n

هل سبق لك أن فتحت مشروعك القديم على JavaScript وفكرت: «من كتب هذا؟ هذه معكرونة كود!»؟ إذا كان الأمر كذلك — مرحبًا بك في النادي. عاجلاً أم آجلاً، يواجه كل مطور موقفًا يتحول فيه الكود إلى فوضى. وهنا تأتي أنماط التصميم في JavaScript للإنقاذ — وهي وصفات مجربة للمهام النمطية.

\n\n

لكن دعنا نتفق فورًا: الأنماط ليست رصاصة فضية. إنها ليست سحرًا يجعل كودك مثاليًا بين ليلة وضحاها. إنها أدوات. وأي أداة تكون جيدة فقط عندما تعرف متى ولماذا تستخدمها. هذا بالضبط ما سنتحدث عنه.

\n\n

ما هي أنماط التصميم بكلمات بسيطة؟

\n\n

تخيل أنك مهندس معماري. أنت لا تخترع شكلاً جديدًا للعجلة أو المدخل في كل مرة. أنت تستخدم حلولاً مجربة: الأقواس، الأعمدة، الجدران الحاملة. أنماط التصميم في JS هي نفس «المخططات المعمارية»، ولكن للكود.

\n\n

إنها تحل ثلاث مشاكل رئيسية:

\n
    \n
  • التكرار — لا حاجة لإعادة اختراع العجلة؛
  • \n
  • قابلية القراءة — مطور آخر سيفهم منطقك فورًا؛
  • \n
  • قابلية التوسع — يمكن توسيع الكود بسهولة دون خطر كسر كل شيء.
  • \n
\n\n

في هذه المقالة، سنستعرض أربعة من أشهر الأنماط التي ستفيدك حقًا في العمل اليومي. لا ماء — فقط كود وممارسة.

\n\n

1. Singleton (الوحيد): عندما تحتاج إلى نسخة واحدة فقط

\n\n

هناك حالات يجب أن يكون فيها نسخة واحدة بالضبط من الفئة في التطبيق. على سبيل المثال:

\n
    \n
  • مخزن الحالة العام (مثل Redux store)؛
  • \n
  • مسجل لتسجيل الأخطاء؛
  • \n
  • اتصال بقاعدة بيانات أو API.
  • \n
\n\n

يضمن نمط Singleton أنه بغض النظر عن عدد المرات التي تحاول فيها إنشاء كائن — ستحصل على نفس الكائن.

\n\n

مثال: عداد الزيارات

\n\n
class Counter {\n  constructor() {\n    if (Counter.instance) {\n      return Counter.instance;\n    }\n    this.count = 0;\n    Counter.instance = this;\n  }\n\n  increment() {\n    this.count++;\n  }\n\n  getCount() {\n    return this.count;\n  }\n}\n\n// الاستخدام\nconst counter1 = new Counter();\nconst counter2 = new Counter();\n\ncounter1.increment();\ncounter1.increment();\n\nconsole.log(counter2.getCount()); // 2 — لأنه نفس الكائن\nconsole.log(counter1 === counter2); // true\n
\n\n

متى تستخدم: عندما يكون من الضروري أن يكون لديك نقطة وصول واحدة للمورد. لكن كن حذرًا — أحد الآثار الجانبية الشائعة لـ Singleton في JS هو الحالة العامة التي يصعب اختبارها. لا تفرط في استخدامه.

\n\n

2. Module (الوحدة النمطية): التغليف بذكاء

\n\n

قبل ظهور ES6 Modules، استخدم المطورون نمط Module لإنشاء دوال خاصة وعامة. حتى الآن، مع وجود import/export، يظل هذا النهج مفيدًا لتنظيم المنطق داخل ملف واحد.

\n\n

السر يكمن في الإغلاقات (closures). ننشئ دالة تُرجع كائنًا بالدوال، بينما تبقى المتغيرات الداخلية غير قابلة للوصول من الخارج.

\n\n

مثال: سلة التسوق لمتجر إلكتروني

\n\n
const ShoppingCart = (function() {\n  // متغيرات خاصة\n  let items = [];\n  \n  // دالة خاصة\n  function calculateTotal() {\n    return items.reduce((sum, item) => sum + item.price * item.quantity, 0);\n  }\n\n  // واجهة عامة\n  return {\n    addItem(product) {\n      const existing = items.find(item => item.id === product.id);\n      if (existing) {\n        existing.quantity++;\n      } else {\n        items.push({ ...product, quantity: 1 });\n      }\n    },\n    removeItem(productId) {\n      items = items.filter(item => item.id !== productId);\n    },\n    getTotal() {\n      return calculateTotal();\n    },\n    clear() {\n      items = [];\n    }\n  };\n}                

المدونات

توصيات الكتب