وداعًا لـ “if” المتداخل! 5 طرق ذهبية لتبسيط الشروط المعقدة في الكود

مقدمة: عندما يتحول الكود إلى متاهة

بتذكر مرة، وأنا بشتغل على مشروع تخرج بالجامعة، كانت عندي مشكلة بسيطة: بدي أتحقق من صلاحية بيانات المستخدم قبل ما أسجلها بالداتابيز. فكرت الموضوع بسيط، شوية “if” وخلصنا. بس يا معلم، بعد شوي صار الكود زي متاهة! “if” جوة “if” جوة “if”… شي بزهق! 🤦‍♂️ وقتها حسيت حالي ضعت بالكود ومش عارف وين البداية ولا النهاية. المشكلة ما كانت بس إنه الكود صعب قراءته، المشكلة الأكبر إنه صار سهل جدًا يصير فيه أخطاء. هاي التجربة علمتني درس مهم: لازم ندور على طرق بديلة عشان نتجنب “if” المتداخلة ونخلي الكود نظيف ومرتب.

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

1. استخدام “Guard Clauses” (الشروط الحارسة)

الـ “Guard Clauses” هي أسلوب بسيط وفعال لتقليل التداخل في الشروط. الفكرة الأساسية هي التحقق من الشروط التي تجعل الدالة غير صالحة للخروج مبكرًا من الدالة. هذا يقلل من الحاجة إلى “if” المتداخلة ويجعل الكود أكثر وضوحًا.

مثال:

بدلًا من:


function processData(data) {
  if (data !== null) {
    if (data.isValid()) {
      // معالجة البيانات
      console.log("Processing data:", data);
    } else {
      console.error("Data is invalid");
    }
  } else {
    console.error("Data is null");
  }
}

نستخدم “Guard Clauses”:


function processData(data) {
  if (data === null) {
    console.error("Data is null");
    return;
  }

  if (!data.isValid()) {
    console.error("Data is invalid");
    return;
  }

  // معالجة البيانات
  console.log("Processing data:", data);
}

نصيحة: استخدم “Guard Clauses” في بداية الدالة للتحقق من الشروط الأساسية. هذا يجعل الكود أسهل للقراءة والفهم.

2. استخدام “Switch” أو “Lookup Tables”

عندما يكون لديك سلسلة من الشروط تعتمد على قيمة متغير واحد، فإن استخدام “switch” أو “Lookup Tables” يمكن أن يكون أكثر وضوحًا وفعالية من استخدام “if” المتداخلة.

مثال:

بدلًا من:


function processAction(action) {
  if (action === "create") {
    // تنفيذ عملية الإنشاء
    console.log("Creating...");
  } else if (action === "update") {
    // تنفيذ عملية التحديث
    console.log("Updating...");
  } else if (action === "delete") {
    // تنفيذ عملية الحذف
    console.log("Deleting...");
  } else {
    console.log("Invalid action");
  }
}

نستخدم “Switch”:


function processAction(action) {
  switch (action) {
    case "create":
      // تنفيذ عملية الإنشاء
      console.log("Creating...");
      break;
    case "update":
      // تنفيذ عملية التحديث
      console.log("Updating...");
      break;
    case "delete":
      // تنفيذ عملية الحذف
      console.log("Deleting...");
      break;
    default:
      console.log("Invalid action");
  }
}

أو نستخدم “Lookup Table”:


const actions = {
  "create": () => console.log("Creating..."),
  "update": () => console.log("Updating..."),
  "delete": () => console.log("Deleting...")
};

function processAction(action) {
  const actionFunction = actions[action];
  if (actionFunction) {
    actionFunction();
  } else {
    console.log("Invalid action");
  }
}

نصيحة: “Lookup Tables” مفيدة بشكل خاص عندما تكون العمليات معقدة وتتطلب تنفيذ دوال مختلفة لكل حالة.

3. تفكيك الشروط المعقدة إلى دوال أصغر

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

مثال:

بدلًا من:


function canAccess(user, resource, permission) {
  if (user.isLoggedIn() &&
      (user.hasPermission(permission) ||
       (resource.owner === user.id && resource.isPublic()))) {
    return true;
  }
  return false;
}

نفكك الشرط:


function isLoggedIn(user) {
  return user.isLoggedIn();
}

function hasPermission(user, permission) {
  return user.hasPermission(permission);
}

function isOwnerAndPublic(user, resource) {
  return resource.owner === user.id && resource.isPublic();
}

function canAccess(user, resource, permission) {
  return isLoggedIn(user) && (hasPermission(user, permission) || isOwnerAndPublic(user, resource));
}

نصيحة: اسم الدالة يجب أن يعكس بوضوح الغرض من الشرط. هذا يجعل الكود سهل الفهم.

4. استخدام “State Pattern” (نمط الحالة)

إذا كان سلوك الكود يعتمد على حالة الكائن، فإن استخدام “State Pattern” يمكن أن يكون حلاً فعالًا. هذا النمط يسمح للكائن بتغيير سلوكه عندما تتغير حالته الداخلية.

مثال:

لنفترض أن لدينا كائن “Order” (طلب) يمكن أن يكون في حالات مختلفة: “Pending” (معلق)، “Shipped” (تم الشحن)، “Delivered” (تم التسليم). بدلاً من استخدام “if” المتداخلة للتحقق من الحالة وتنفيذ عمليات مختلفة، يمكننا استخدام “State Pattern”.


// تعريف واجهة الحالة
class OrderState {
  constructor(name) {
    this.name = name;
  }
  process(order) {
    throw new Error("This method should be overridden");
  }
}

// تعريف الحالات المختلفة
class PendingState extends OrderState {
  constructor() {
    super("Pending");
  }
  process(order) {
    console.log("Processing pending order...");
    order.setState(new ShippedState());
  }
}

class ShippedState extends OrderState {
  constructor() {
    super("Shipped");
  }
  process(order) {
    console.log("Processing shipped order...");
    order.setState(new DeliveredState());
  }
}

class DeliveredState extends OrderState {
  constructor() {
    super("Delivered");
  }
  process(order) {
    console.log("Order is already delivered.");
  }
}

// تعريف كائن الطلب
class Order {
  constructor() {
    this.state = new PendingState();
  }

  setState(state) {
    this.state = state;
  }

  process() {
    this.state.process(this);
  }
}

// استخدام
const order = new Order();
order.process(); // Processing pending order...
order.process(); // Processing shipped order...
order.process(); // Order is already delivered.

نصيحة: “State Pattern” مفيد بشكل خاص عندما يكون لديك عدد كبير من الحالات والانتقالات بينها.

5. استخدام “Boolean Algebra” (الجبر البولياني)

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

مثال:

لنفترض أن لدينا الشرط التالي:


if (!(x > 10 && y < 5)) {
  // تنفيذ شيء ما
}

باستخدام قانون دي مورغان، يمكننا تبسيط هذا الشرط إلى:


if (x <= 10 || y >= 5) {
  // تنفيذ شيء ما
}

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

الخلاصة: الكود النظيف يبدأ بالشروط الواضحة ✨

تجنب "if" المتداخلة ليس مجرد مسألة جمالية، بل هو ضرورة لجعل الكود أكثر قابلية للقراءة والصيانة. استخدام "Guard Clauses"، و "Switch"، وتفكيك الشروط، و "State Pattern"، والجبر البولياني، كلها أدوات قوية يمكن أن تساعدك في تبسيط الشروط المعقدة وتحسين جودة الكود. تذكر دائمًا: الكود الجيد ليس فقط الكود الذي يعمل، بل هو الكود الذي يمكن فهمه وتعديله بسهولة من قبل الآخرين (وحتى من قبلك بعد مرور بعض الوقت! 😉).

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

أبو عمر

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

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

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

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

آخر المدونات

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

تحديثات قاعدة البيانات بدون توقف: كيف أنقذنا نمط التوسيع والتعاقد (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 قراءة المزيد
البودكاست