أرقامي السحرية كانت لعنة الصيانة: كيف أنقذتني ‘الثوابت المسماة’ من جحيم التخمين؟

يا أهلاً وسهلاً فيكم يا جماعة الخير. بتذكر مرة، زمان، يمكن في 2012 أو 2013، كنت شغال على نظام محاسبة صغير لشركة محلية. كنت وقتها لسا في بداياتي، متحمس أكتب كود وأشوفه شغال، وما كنت كثير أفكر في المستقبل أو في “مين بده يصلّح وراي”.

المهم، كان في النظام جزئية بتحسب ضريبة القيمة المضافة، وكانت وقتها 14%. فبكل بساطة، وين ما كنت أحتاج أحسب الضريبة، كنت أضرب الرقم بـ 0.14. في فاتورة المبيعات، في تقرير الأرباح، في عرض سعر للزبون… كله كان فيه الرقم 0.14 منتشر زي حبات العدس في المجدرة.

بعد سنة تقريباً، الحكومة قررت تغير نسبة الضريبة وتخليها 16%. اتصل علي صاحب الشركة، وكان مستعجل، “أبو عمر، بدنا نغير الضريبة بسرعة، القانون الجديد ببلش من بكرة!”. قلتله “بسيطة، ولا يهمك، كلها تعديل رقم”. يا ريتني ما قلتها! قضيت ليلة كاملة يا جماعة وأنا بفتش في كل ملفات المشروع عن الرقم 0.14. والمشكلة الأكبر، إني كنت خايف أغير رقم 0.14 يكون مستخدم لشي ثاني غير الضريبة! شو هالحكي؟ هل هو خصم معين؟ نسبة عمولة؟ وجع راس ما بعده وجع راس.

بعد ساعات من البحث والتخمين والخوف، عملت التعديلات ورفعت النسخة الجديدة. ثاني يوم الصبح، تلفون ثاني من الزبون، بس هالمرة صوته مش مبسوط أبداً. اكتشفنا إنه في تقرير نادر الاستخدام، نسيت أغير الرقم فيه، وكان النظام بيعطي أرقام غلط. الموقف كان محرج جداً، ومن يومها وأنا حامل درس “الأرقام السحرية” معي وين ما أروح. هاي القصة هي اللي خلتني أكتبلكم اليوم عن هالموضوع المهم.

ما هي “الأرقام السحرية” (Magic Numbers)؟ ولماذا هي “لعنة”؟

ببساطة، الرقم السحري هو أي رقم بتستخدمه في الكود تبعك بدون ما يكون له اسم أو معنى واضح. هو مجرد رقم “انبثق من العدم” وظهر في معادلة أو شرط. الرقم 0.14 في قصتي كان رقمًا سحريًا. الرقم 86400 في كود للتحقق من انتهاء صلاحية الجلسة هو رقم سحري (بالمناسبة، هذا عدد الثواني في اليوم).

ليش هي لعنة حقيقية على المبرمجين؟ للأسباب التالية:

1. جحيم التخمين وصعوبة الفهم

لما تشوف كود زي هيك بعد 6 شهور من كتابته (أو لو زميلك اللي شافه):


if (userStatus == 2) {
  // ... do something
}

أول سؤال بيخطر في بالك: “شو يعني 2؟”. هل يعني المستخدم فعال (active)؟ محظور (banned)؟ ينتظر التفعيل (pending)؟ ولا يمكن يكون مدير للنظام (admin)؟ أنت مضطر تبحث في باقي الكود أو في قاعدة البيانات عشان تفهم معنى هذا الرقم. هذا تضييع للوقت والجهد.

2. كابوس الصيانة والتعديلات الخطرة

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

3. خطر الأخطاء المطبعية (Typos)

الأرقام الطويلة سهلة الخطأ. تخيل إنك بتتعامل مع عدد الثواني في اليوم (86400). من السهل جداً تكتبها بالخطأ 84600. المترجم (Compiler) أو المفسر (Interpreter) ما راح يعترض، لأنها بالنسبة له مجرد رقم صحيح. لكن منطق البرنامج تبعك راح يكون فيه خطأ فادح صعب اكتشافه.

الحل السحري الحقيقي: الثوابت المسماة (Named Constants)

الحل، يا جماعة الخير، بسيط وأنيق جداً: لا تستخدم أرقاماً مجردة، بل أعطِها أسماءً ذات معنى. هذه الأسماء بنسميها “الثوابت المسماة” (Named Constants). الثابت هو متغير قيمته لا تتغير بعد إعطائها له أول مرة.

خلينا نعيد كتابة الأمثلة السابقة باستخدام الثوابت المسماة ونشوف الفرق الشاسع.

مثال عملي: من الجحيم إلى النعيم

الكود السيء (باستخدام الأرقام السحرية):


// JavaScript Example

function calculateFinalPrice(price, itemsCount) {
  // What is 0.16? VAT?
  const tax = price * 0.16;
  
  // What is 50? Shipping cost? Or a free shipping threshold?
  let shippingCost = 50; 
  if (price > 1000) {
    shippingCost = 0; // Free shipping
  }

  return price + tax + shippingCost;
}

function checkUserAccess(user) {
  // What is 2? What is 3?
  if (user.status === 2 || user.status === 3) {
    return true; // Has access
  }
  return false;
}

الكود النظيف (باستخدام الثوابت المسماة):


// JavaScript Example

// Constants are defined in one clear place
const VAT_RATE = 0.16;
const STANDARD_SHIPPING_COST = 50;
const FREE_SHIPPING_THRESHOLD = 1000;

const USER_STATUS_ACTIVE = 2;
const USER_STATUS_ADMIN = 3;

function calculateFinalPrice(price, itemsCount) {
  const tax = price * VAT_RATE;
  
  let shippingCost = STANDARD_SHIPPING_COST;
  if (price > FREE_SHIPPING_THRESHOLD) {
    shippingCost = 0; // Free shipping
  }

  return price + tax + shippingCost;
}

function checkUserAccess(user) {
  if (user.status === USER_STATUS_ACTIVE || user.status === USER_STATUS_ADMIN) {
    return true; // Has access
  }
  return false;
}

شوف الفرق! الكود الثاني يقرأ كأنه جملة إنجليزية (أو عربية لو كتبنا بأسماء عربية). واضح، صريح، ومباشر. لو تغيرت الضريبة بكرة، كل ما عليك فعله هو تغيير قيمة VAT_RATE في مكان واحد فقط. يا سلام على الراحة!

نصائح أبو عمر الذهبية للتعامل مع الثوابت

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

متى لا يعتبر الرقم “سحرياً”؟

مش كل رقم هو رقم سحري. الأرقام اللي معناها واضح جداً من السياق، زي 0 و 1، غالباً ما بتكون سحرية. مثلاً:

  • for (let i = 0; i < 10; i++): الصفر هنا واضح أنه نقطة بداية العد.
  • if (items.length > 0): الصفر هنا يعني “هل القائمة فارغة أم لا؟”.
  • x = y * -1;: الرقم -1 واضح أنه لقلب إشارة الرقم.

القاعدة الأساسية: إذا كان الرقم يحمل معنى “تجاري” أو معنى خاص بنظامك (مثل نسبة الضريبة، عدد المحاولات المسموح بها، حالة المستخدم)، فهو مرشح ممتاز ليصبح ثابتًا مسمى.

أفضل الممارسات في التسمية

“الأسماء في البرمجة هي نصف المعركة. اسم جيد يغنيك عن كتابة تعليق.” – أبو عمر

  • استخدم حالة الأحرف الكبيرة (UPPER_SNAKE_CASE): هذا هو العرف الشائع في معظم لغات البرمجة للتمييز بين الثوابت والمتغيرات العادية. مثال: MAX_LOGIN_ATTEMPTS.
  • كن وصفيًا قدر الإمكان: اسم مثل RATE غامض. لكن ANNUAL_INTEREST_RATE واضح تمامًا. لا تخف من الأسماء الطويلة طالما أنها توضح المعنى.

أين تضع ثوابتك؟

تنظيم الثوابت مهم جداً، خصوصاً في المشاريع الكبيرة.

  • للمشاريع الصغيرة أو الملفات البسيطة: يمكنك وضع الثوابت في أعلى الملف الذي يستخدمها.
  • للمشاريع الكبيرة: الحل الأفضل هو إنشاء ملف خاص بالثوابت والإعدادات، مثلاً constants.js أو config.py. هذا الملف يصبح “مصدر الحقيقة الوحيد” (Single Source of Truth) لكل القيم الثابتة في مشروعك. أي تعديل يتم في هذا الملف المركزي وينعكس على كل المشروع.

لا يقتصر الأمر على الأرقام! (احذر من النصوص السحرية)

نفس المبدأ ينطبق تمامًا على النصوص (Strings). استخدام نصوص مجردة في الشروط يمكن أن يسبب نفس المشاكل.

سيء: if (user.role === 'administrator')

جيد: const ROLE_ADMIN = 'administrator'; if (user.role === ROLE_ADMIN)

هذا يحميك من الأخطاء الإملائية (هل هي ‘administrator’ أم ‘admin’؟) ويسهل التعديل لو قررت تغيير أسماء الأدوار في المستقبل.

الخلاصة: اجعل كودك يروي قصة واضحة 📖

في النهاية يا جماعة، كتابة الكود لا تختلف كثيراً عن كتابة قصة. كلما كانت قصتك أوضح وأسهل للفهم، كلما كان التعامل معها في المستقبل أمتع وأقل إرهاقاً. الأرقام السحرية هي كلمات غامضة في قصتك، تجعل القارئ (سواء كان أنت في المستقبل أو زميلك) يتوقف ويسأل: “ماذا يقصد المؤلف هنا؟”.

الثوابت المسماة هي بطل القصة الذي يوضح كل شيء. هي تترجم الغموض إلى وضوح، وتحول الصيانة من كابوس إلى عملية بسيطة وآمنة. نصيحتي الأخيرة لكم: في المرة القادمة التي تكتب فيها رقماً في الكود، توقف لحظة واسأل نفسك: “هل هذا الرقم له معنى خاص؟”. إذا كانت الإجابة “نعم”، فامنحه اسماً جميلاً يستحقه. كودك سيشكرك لاحقاً. 😉

ودمتم سالمين ومبدعين.

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

تسويق رقمي

عملاؤنا المحتملون كانوا أشباحًا: كيف أنقذتنا “نمذجة الإحالة القائمة على البيانات” من جحيم تتبع الإعلانات الأعمى؟

أشارككم قصة حقيقية من قلب المعركة التقنية، كيف كنا نحرق ميزانيات التسويق على أشباح لا نراها، وكيف استطعنا باستخدام الذكاء الاصطناعي ونمذجة الإحالة القائمة على...

10 أبريل، 2026 قراءة المزيد
تجربة المستخدم والابداع البصري

تطبيقاتنا كانت تستبعد الملايين: كيف أنقذتنا ‘إرشادات الوصول الرقمي’ (WCAG) من جحيم الإقصاء؟

أنا أبو عمر، مبرمج فلسطيني، وهذه قصتي مع لحظة "صادمة" جعلتني أدرك أن تطبيقاتي التي كنت أفتخر بها، كانت في الحقيقة جداراً عازلاً لملايين المستخدمين....

10 أبريل، 2026 قراءة المزيد
الحوسبة السحابية

بيئاتنا السحابية كانت فوضى: كيف أنقذتنا البنية التحتية كشيفرة (IaC) من جحيم الانحراف؟

أشارككم قصة حقيقية من قلب المعركة التقنية، كيف انتقلنا من فوضى النقرات اليدوية والانحراف في إعدادات السحابة إلى عالم منظم ومتناغم بفضل "البنية التحتية كشيفرة"...

10 أبريل، 2026 قراءة المزيد
التوظيف وبناء الهوية التقنية

مقابلات التوظيف ليست مجرد أكواد: كيف تحكي قصتك التقنية باستخدام إطار STAR لتبهر مديري التوظيف؟

مقابلات العمل التقنية تتجاوز حل المسائل البرمجية؛ إنها فرصتك لسرد قصة مقنعة عن مهاراتك. تعلم معي، أنا أبو عمر، كيف تستخدم إطار STAR لتحويل تجاربك...

10 أبريل، 2026 قراءة المزيد
التوسع والأداء العالي والأحمال

قاعدة بياناتنا كانت على وشك الانهيار: كيف أنقذتنا ‘الذاكرة المخبئية الموزعة’ من جحيم الاستعلامات المتكررة؟

في لحظة حرجة، كادت قاعدة بياناتنا أن تنهار تحت ضغط هائل من الاستعلامات المتكررة. أشارككم قصتنا وكيف كانت "الذاكرة المخبئية الموزعة" (Distributed Caching) باستخدام Redis...

10 أبريل، 2026 قراءة المزيد
التكنلوجيا المالية Fintech

بيانات بطاقات عملائنا كانت قنبلة موقوتة: كيف أنقذنا ‘الترميز’ (Tokenization) من جحيم خروقات البيانات؟

في هذه المقالة، أشارككم قصة حقيقية عن الخطر الذي كاد أن يدمر شركتنا بسبب تخزين بيانات البطاقات البنكية، وكيف كان "الترميز" (Tokenization) هو طوق النجاة....

10 أبريل، 2026 قراءة المزيد
البودكاست