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

ليلة لا تُنسى: عندما تحولت القلعة إلى زجاج

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

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

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

تلك الليلة كانت درساً قاسياً، لكنها كانت أيضاً نقطة تحول. تعلمنا بالطريقة الصعبة أن كتابة كود “يعمل” في الظروف المثالية لا يكفي. يجب أن نكتب كوداً “يصمد” في أسوأ الظروف. ومن هنا بدأت رحلتنا الحقيقية مع ما يسمى بـ “البرمجة الدفاعية” (Defensive Programming).

ما هي البرمجة الدفاعية بالضبط؟

تخيل أنك تقود سيارتك في شارع مزدحم. هل تفترض أن كل السائقين الآخرين محترفون وسيلتزمون بالقوانين 100%؟ بالطبع لا. السائق الحذِر (الدفاعي) يتوقع الأسوأ: قد يتجاوز أحدهم الإشارة الحمراء، أو يغير مساره فجأة بدون إشارة. لذلك، يترك مسافة أمان، ينظر في المرايا باستمرار، ويكون مستعداً للضغط على المكابح في أي لحظة.

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

البرمجة الدفاعية ليست مجرد مجموعة من التقنيات، بل هي عقلية ومسؤولية تقع على عاتق كل مبرمج يسعى لكتابة كود احترافي وموثوق.

أسلحة أبو عمر في ترسانة البرمجة الدفاعية

على مر السنين، جمعتُ ترسانة من المبادئ والتقنيات التي أطبقها في كل مشروع. هذه ليست مجرد نظريات، بل هي أسلحة مجربة في ميدان المعركة البرمجية.

1. التحقق من المدخلات (Input Validation): لا تثق بأحد!

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

مثال عملي (JavaScript):

لنفترض أن لدينا دالة تقوم بحجز موعد لمستخدم. النسخة “الساذجة” قد تبدو هكذا:

// النسخة الساذجة (قلعة من زجاج)
function bookAppointment(userId, date) {
  // ... منطق حجز الموعد مباشرة باستخدام userId و date
  console.log(`تم حجز موعد للمستخدم ${userId} في تاريخ ${date.toISOString()}`);
}

// استدعاء قد يسبب كارثة
bookAppointment(null, "2023-10-27"); // 😱 ماذا سيحدث؟

هنا، إذا تم تمرير `userId` كـ `null` أو `date` كنص غير صالح، قد تنهار الدالة أو تسجل بيانات فاسدة في قاعدة البيانات. النسخة “الدفاعية” ستكون مختلفة تماماً:

// النسخة الدفاعية (حصن منيع)
function bookAppointmentDefensive(userId, date) {
  // 1. التحقق من وجود ونوعية المدخلات (Pre-conditions)
  if (!userId || typeof userId !== 'string' || userId.trim() === '') {
    throw new Error("معرّف المستخدم غير صالح.");
  }

  // 2. التحقق من أن التاريخ هو كائن تاريخ صالح
  if (!(date instanceof Date) || isNaN(date)) {
    throw new Error("صيغة التاريخ غير صالحة.");
  }
  
  // 3. التحقق من منطق العمل (Business Logic Validation)
  const today = new Date();
  today.setHours(0, 0, 0, 0); // تجاهل الوقت
  if (date < today) {
    throw new Error("لا يمكن حجز موعد في الماضي.");
  }

  // الآن فقط، بعد كل الفحوصات، يمكننا الوثوق بالبيانات
  console.log(`تم حجز موعد للمستخدم ${userId} في تاريخ ${date.toISOString()}`);
  // ... منطق حجز الموعد الفعلي
}

// استدعاء آمن
try {
  bookAppointmentDefensive("user-123", new Date("2024-05-20")); // يعمل بنجاح
  bookAppointmentDefensive(null, new Date()); // سيطلق خطأ يمكن معالجته
} catch (error) {
  console.error("فشل حجز الموعد:", error.message);
}

2. معالجة الأخطاء بذكاء: مش كل مصيبة بدها فضيحة!

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

  • الفشل الصامت (Fail-Silent): تسجيل الخطأ في الخلفية والمتابعة بقيمة افتراضية. مفيد في الحالات غير الحرجة.
  • الفشل الآمن (Fail-Safe): إعادة النظام إلى حالة آمنة. مثلاً، في نظام مالي، إذا فشلت عملية تحويل، يجب إلغاء العملية بالكامل بدلاً من خصم المبلغ من طرف وعدم إضافته للطرف الآخر.
  • إعلام المستخدم: عرض رسالة واضحة ومفيدة للمستخدم تشرح المشكلة وكيف يمكن حلها، بدلاً من عرض رسالة خطأ تقنية غامضة.

مثال عملي (Python): جلب بيانات من API قد يكون غير متاح.

import requests
import json

# النسخة الساذجة
def get_user_profile_naive(user_id):
    response = requests.get(f"https://api.example.com/users/{user_id}")
    return response.json() # إذا فشل الطلب، سينهار البرنامج هنا

# النسخة الدفاعية
def get_user_profile_defensive(user_id):
    try:
        response = requests.get(f"https://api.example.com/users/{user_id}", timeout=5)
        
        # التحقق من أن الطلب نجح (e.g., 200 OK)
        response.raise_for_status() # يطلق خطأ إذا كان كود الحالة 4xx أو 5xx

        return response.json()

    except requests.exceptions.RequestException as e:
        # API غير متاح أو هناك مشكلة في الشبكة
        print(f"خطأ في الشبكة: {e}")
        # يمكننا إرجاع بيانات من الكاش أو قيمة افتراضية
        return {"name": "مستخدم غير معروف", "error": "لا يمكن الوصول للخدمة حالياً"}
    except json.JSONDecodeError:
        # API أرجع بيانات غير صالغة (ليست JSON)
        print("خطأ: استجابة غير صالحة من الخادم")
        return {"name": "مستخدم غير معروف", "error": "خطأ في بيانات الخادم"}

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

3. استخدام التأكيدات (Assertions): الفحص الداخلي للقلعة

التأكيدات (Assertions) هي أدوات للمبرمج، وليست للمستخدم. إنها عبارة عن شروط تضعها في الكود للتحقق من صحة افتراضاتك كمبرمج. إذا كان الشرط خاطئاً، فإن التأكيد يطلق خطأ فادحاً ويوقف البرنامج (في وضع التطوير عادةً).

الفكرة هي: “أنا، كمبرمج، متأكد 100% أن هذه القيمة يجب أن تكون موجبة في هذه المرحلة. إذا لم تكن كذلك، فهناك خطأ فادح في منطق البرنامج يجب إصلاحه فوراً”.

مثال عملي (Python):

def calculate_discount(price, discount_percentage):
    # نتحقق من المدخلات القادمة من الخارج
    if price < 0:
        raise ValueError("السعر لا يمكن أن يكون سالباً")
    
    # ... حسابات داخلية ...
    final_price = price * (1 - discount_percentage)
    
    # تأكيد (Assertion) للتحقق من منطقنا الداخلي
    # من المستحيل منطقياً أن يكون السعر النهائي أعلى من الأصلي
    assert final_price <= price, "خطأ منطقي فادح: السعر بعد الخصم أعلى من الأصلي!"
    
    return final_price

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

4. مبدأ الامتياز الأقل (Principle of Least Privilege)

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

نصيحة من أبو عمر: بدلاً من تمرير كائن `User` الكامل (بما فيه كلمة المرور والبريد الإلكتروني وكل شيء) إلى دالة كل ما تحتاجه هو عرض اسم المستخدم، مرّر لها اسم المستخدم فقط (`user.name`). هذا يقلل من الآثار الجانبية غير المتوقعة ويجعل من الصعب على خطأ في دالة صغيرة أن يفسد بيانات حساسة في مكان آخر.

خلاصة الكلام ونصيحة من القلب

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

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

ابدأ اليوم، حتى لو بخطوات صغيرة. في كل دالة تكتبها، اسأل نفسك: “ما هي أسوأ الأشياء التي يمكن أن تحدث هنا؟ وكيف يمكنني حماية الكود منها؟”.

خلي كودك حصن منيع، مش قلعة من قزاز. وسلامتكم! 💪

أبو عمر

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

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

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

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

آخر المدونات

برمجة وقواعد بيانات

تحديثات قاعدة البيانات بدون توقف: كيف أنقذنا نمط التوسيع والتعاقد (Expand/Contract) من جحيم التوقفات المجدولة؟

هل سئمت من إيقاف الخدمة مع كل تحديث لهيكلة قاعدة البيانات؟ أشارككم قصة حقيقية وكيف أنقذنا نمط التوسيع والتعاقد (Expand/Contract) من ليالي النشر الطويلة والمُجهدة،...

4 يونيو، 2026 قراءة المزيد
الشبكات والـ APIs

كانت إعادة المحاولة كارثة: كيف أنقذتنا مفاتيح عدم تكرار العمليات (Idempotency Keys) من جحيم الفواتير المزدوجة؟

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

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

من التوقف التام إلى النجاة: كيف أنقذتنا استراتيجية “الضوء المرشد” (Pilot Light) يوم انقطعت السحابة؟

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

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

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

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

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

من الانتظار لأيام إلى الدفع في ثوانٍ: كيف أنقذتنا شبكات الدفع الفوري من جحيم التحويلات البنكية؟

أسرد لكم من واقع تجربتي كـ "أبو عمر"، كيف عانينا من بطء وتكلفة التحويلات البنكية الدولية، وكيف جاءت شبكات الدفع الفوري ومعيار ISO 20022 لتكون...

4 يونيو، 2026 قراءة المزيد
البنية التحتية وإدارة السيرفرات

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

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

4 يونيو، 2026 قراءة المزيد
اختبارات الاداء والجودة

كانت تغطية الاختبارات 100% لكن الأخطاء تتسرب: كيف أنقذنا “الاختبار الطفري” من جحيم الثقة الزائفة؟

كنا نظن أن تغطية الاختبار بنسبة 100% هي درعنا الواقي، لكن الأخطاء كانت تتسلل إلى الإنتاج كاللصوص في ليل بهيم. اكتشف كيف أنقذنا "الاختبار الطفري"...

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