أكوادنا كانت طلاسم رقمية: كيف أنقذتنا ‘الثوابت المسماة’ (Named Constants) من جحيم الأرقام السحرية؟

“يا زلمة، شو قصة هاد الرقم 86400؟”

خليني أرجع فيكم بالزمن لأيام زمان، أيام ما كنت لسا مبرمج جديد وشعري أسود أكثر من هلأ. كنا شغالين على نظام إدارة محتوى لعميل مهم، وكان في جزء من النظام مسؤول عن “الكاش” (Caching)، يعني تخزين البيانات بشكل مؤقت لتسريع الموقع. كل شي كان تمام، والنظام شغال زي الساعة.

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

في ليلة من هالليالي، وأنا شبه مستسلم وبشرب فنجان القهوة رقم مليون، لمحت سطر كود بسيط في ملف الإعدادات:


// Set cache expiration
$cache->setExpiration(86400);

سألت زميلي اللي كان أكبر مني خبرة: “يا خليل، شو قصة هاد الرقم 86400؟”.

طلع فيّي بنظرة فيها خليط من “معقول ما بتعرف؟” و “أخيراً لقيناها”. حكالي: “يا أبو عمر، هاد عدد الثواني في اليوم الواحد (24 ساعة * 60 دقيقة * 60 ثانية). الكاش بتنتهي صلاحيته كل 24 ساعة”.

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

بهديك اللحظة، تعلّمت درس من أهم الدروس في مسيرتي المهنية: لا مكان للأرقام السحرية في الكود النظيف. ومن يومها، أعلنت الحرب عليها، وكان سلاحي هو “الثوابت المسماة”.


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

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

مثال على كود مليء بالطلاسم

تخيل إنك بتقرأ الكود التالي لأول مرة في مشروع جديد:


function calculateOrderTotal(price, userStatus, shippingMethod) {
    let finalPrice = price;

    // Apply discount based on user status
    if (userStatus == 2) {
        finalPrice = price * 0.90; // 10% discount
    }

    // Add shipping cost
    if (shippingMethod == 1) {
        finalPrice += 15;
    } else {
        finalPrice += 30;
    }

    // Apply tax
    return finalPrice * 1.16;
}

هذا الكود شغال، لكنه كارثة حقيقية لأي شخص سيقرأه أو يحاول صيانته لاحقاً (حتى لو كنت أنت نفسك بعد 6 أشهر). الأسئلة اللي بتخطر ببالك فوراً:

  • ماذا يعني userStatus == 2؟ هل هو مستخدم “ذهبي”؟ “نشط”؟ “مسجل جديد”؟
  • ليش الخصم 0.90؟ هل هي 10% دائماً؟
  • ماذا يمثل shippingMethod == 1؟ هل هو شحن عادي أم سريع؟
  • من أين أتى الرقم 15 و 30؟
  • وما هذا الرقم 1.16؟ هل هو ضريبة القيمة المضافة؟ ضريبة مبيعات؟

المشاكل الكارثية التي تسببها

  1. الغموض المطلق: الكود صعب الفهم ويجبرك على التخمين أو البحث في أماكن أخرى عن معنى هذه الأرقام.
  2. صعوبة الصيانة: تخيل لو أن نسبة الضريبة تغيرت من 16% إلى 17%. ستحتاج للبحث عن كل الأماكن التي استخدمت فيها الرقم 1.16 وتغييرها. ماذا لو كان هذا الرقم مستخدماً في 20 ملفاً مختلفاً؟ من السهل جداً أن تنسى تعديل إحداها، مما يسبب أخطاء فادحة في الحسابات.
  3. مصدر للأخطاء (Bugs): عند تكرار كتابة نفس الرقم يدوياً، تزيد فرصة حدوث خطأ إملائي. قد تكتب 1.16 في مكان و 1.15 في مكان آخر عن طريق الخطأ.

باختصار، الأرقام السحرية تحوّل الكود إلى حقل ألغام، كل خطوة صيانة فيه قد تؤدي إلى انفجار لم تكن تتوقعه.


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

الحل بسيط وأنيق بشكل لا يصدق: أعطِ هذه الأرقام الغامضة أسماءً واضحة وذات معنى. هذه الأسماء هي ما نسميه “الثوابت المسماة”. الثابت هو متغير لا يمكن تغيير قيمته بعد إعلانه.

إعادة كتابة المثال السابق بشكل نظيف

دعونا نرى كيف سيبدو نفس الكود السابق بعد استخدام الثوابت. سنفترض أننا نستخدم JavaScript كمثال.


// Define constants in a central place
const USER_STATUS_VIP = 2;
const VIP_DISCOUNT_RATE = 0.90; // Represents a 10% discount

const SHIPPING_METHOD_NORMAL = 1;
const SHIPPING_METHOD_EXPRESS = 2;

const NORMAL_SHIPPING_COST = 15;
const EXPRESS_SHIPPING_COST = 30;

const VAT_RATE = 1.16; // 16% Value Added Tax

function calculateOrderTotal(price, userStatus, shippingMethod) {
    let finalPrice = price;

    // Apply discount based on user status
    if (userStatus == USER_STATUS_VIP) {
        finalPrice = price * VIP_DISCOUNT_RATE;
    }

    // Add shipping cost
    if (shippingMethod == SHIPPING_METHOD_NORMAL) {
        finalPrice += NORMAL_SHIPPING_COST;
    } else {
        finalPrice += EXPRESS_SHIPPING_COST;
    }

    // Apply tax
    return finalPrice * VAT_RATE;
}

انظر إلى الفرق! الكود الآن يقرأ كأنه جملة إنجليزية (أو عربية لو كانت المتغيرات بالعربي). أصبح “يشرح نفسه بنفسه”.

  • نعرف الآن أن userStatus == 2 يعني أن المستخدم هو “VIP”.
  • إذا تغيرت نسبة الضريبة، كل ما علينا فعله هو تغيير قيمة VAT_RATE في مكان واحد فقط!
  • لا يوجد مجال للخطأ في كتابة الأرقام، لأننا نستخدم أسماء الثوابت في كل مكان.

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

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

متى أستخدم الثابت؟ القاعدة بسيطة!

اسأل نفسك سؤالين:

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

مثلاً، بدلاً من كتابة:


// Wait for 3 seconds (3000 milliseconds) before retrying
setTimeout(doSomething, 3000);

اكتبها هكذا:


const RETRY_DELAY_MS = 3000;
setTimeout(doSomething, RETRY_DELAY_MS);

الكود الثاني لا يحتاج إلى تعليق، فالاسم واضح تماماً.

فن اختيار الأسماء (Naming Conventions)

اسم الثابت لا يقل أهمية عن استخدامه. اختر اسماً وصفياً وواضحاً. القاعدة المتعارف عليها في معظم لغات البرمجة هي استخدام الأحرف الكبيرة مع شرطة سفلية للفصل بين الكلمات (UPPER_SNAKE_CASE).

  • سيء: const N = 10;
  • جيد: const ITEMS_PER_PAGE = 10;
  • سيء: const T = 3600;
  • ممتاز: const SESSION_TIMEOUT_SECONDS = 3600;

نظّم ثوابتك في مكان مركزي

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

مثال في لغة Python:


# file: config.py

# --- User Roles ---
ROLE_ADMIN = "admin"
ROLE_EDITOR = "editor"
ROLE_VIEWER = "viewer"

# --- API Settings ---
API_BASE_URL = "https://api.my-app.com/v2/"
API_REQUEST_TIMEOUT_SECONDS = 15

# --- Pagination ---
DEFAULT_PAGE_SIZE = 25

الآن، في أي ملف آخر، يمكنك ببساطة استيراد هذه الإعدادات واستخدامها:


# file: user_service.py
import config

def check_permissions(user):
    if user.role == config.ROLE_ADMIN:
        print("Admin has full access.")
    # ...

هذا التنظيم يجعل الكود قابلاً للتطوير بشكل هائل.


الخلاصة: من طلاسم إلى كود يتنفس وضوحًا 📜

التخلص من “الأرقام السحرية” واستبدالها بـ “الثوابت المسماة” ليس مجرد تفضيل شخصي أو “موضة” برمجية، بل هو أحد أعمدة كتابة الكود النظيف والقابل للصيانة (Clean and Maintainable Code).

تذكر دائماً:

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

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

أبو عمر

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

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

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

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

آخر المدونات

ذكاء اصطناعي

نماذجنا اللغوية كانت تهلوس: كيف أنقذنا التوليد المعزز بالاسترجاع (RAG) من جحيم المعلومات الخاطئة؟

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

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

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

بتذكر مرة كُنا نبني لوحة تحكم معقدة، وصارت زي قمرة قيادة طائرة حربية من كثرة الأزرار والمؤشرات. في هذه المقالة، بحكي لكم كيف اكتشفنا مفهوم...

13 أبريل، 2026 قراءة المزيد
برمجة وقواعد بيانات

بحثنا كان يزحف كالسلحفاة: كيف أنقذتنا ‘فهارس قاعدة البيانات’ (Database Indexing) من جحيم المسح الكامل للجدول؟

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

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

بنيتنا التحتية كانت قصورًا من رمال: كيف أنقذتنا ‘البنية التحتية كشيفرة’ (IaC) من جحيم الانحراف في الإعدادات؟

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

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

ملفي الشخصي على GitHub كان مدينة أشباح: كيف أنقذتني ‘المشاريع المثبتة والـ READMEs’ من جحيم التجاهل؟

هل تشعر أن ملفك على GitHub لا يعكس خبرتك الحقيقية ويتم تجاهله من قبل مسؤولي التوظيف؟ في هذه المقالة، أشاركك قصتي وكيف حولت ملفي من...

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

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

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

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