تخطَّ إلى المحتوى

🧩 شرح أنماط التصميم (Design Patterns)

نمط Chain of Responsibility

الدرس 26 من 28· ⏱ 3 دقائق قراءة

ما هو نمط Chain of Responsibility؟

نمط Chain of Responsibility سلوكي (Behavioral) يمرّر الطلب عبر سلسلة من المعالجين (Handlers)—كل معالج يقرر إما يتعامل مع الطلب، أو يمرره للمعالج التالي في السلسلة. الطالب لا يعرف مسبقًا مين بالضبط راح يعالج طلبه.

المشكلة

نظام دعم فني: كل طلب لازم يتصعّد حسب نوعه ومستوى تعقيده:

// قبل النمط — شروط متشعبة تكبر مع كل مستوى دعم جديد
function handleTicket(ticket) {
  if (ticket.type === "billing" && ticket.priority === "low") {
    console.log("الدعم المستوى 1 يحل المشكلة");
  } else if (ticket.type === "technical" && ticket.priority === "medium") {
    console.log("الدعم المستوى 2 يحل المشكلة");
  } else if (ticket.priority === "critical") {
    console.log("المدير يتدخل مباشرة");
  } else {
    console.log("لا يوجد من يعالج هذا الطلب");
  }
}

⚠️ كل نوع تذكرة جديد يعني تعديل هذه الدالة—وتكبر مع الوقت لتصبح غير قابلة للصيانة.

الحل — سلسلة معالجين

class SupportHandler {
  setNext(handler) {
    this.next = handler;
    return handler; // يسمح بسلسلة .setNext().setNext()
  }

  handle(ticket) {
    if (this.next) {
      return this.next.handle(ticket);
    }
    console.log("لا يوجد من يعالج هذا الطلب");
  }
}

class LevelOneSupport extends SupportHandler {
  handle(ticket) {
    if (ticket.priority === "low") {
      console.log("الدعم المستوى 1 يحل المشكلة");
    } else {
      super.handle(ticket); // مرّرها للتالي
    }
  }
}

class LevelTwoSupport extends SupportHandler {
  handle(ticket) {
    if (ticket.priority === "medium") {
      console.log("الدعم المستوى 2 يحل المشكلة");
    } else {
      super.handle(ticket);
    }
  }
}

class Manager extends SupportHandler {
  handle(ticket) {
    if (ticket.priority === "critical") {
      console.log("المدير يتدخل مباشرة");
    } else {
      super.handle(ticket);
    }
  }
}

// بناء السلسلة
const levelOne = new LevelOneSupport();
const levelTwo = new LevelTwoSupport();
const manager = new Manager();

levelOne.setNext(levelTwo).setNext(manager);

levelOne.handle({ priority: "low" }); // الدعم المستوى 1 يحل المشكلة
levelOne.handle({ priority: "critical" }); // المدير يتدخل مباشرة

كل معالج مسؤول عن قرار واحد بسيط: يعالج، أو يمرر. تقدر تضيف أو تعيد ترتيب معالجين بدون لمس أي معالج آخر.

الاسم مألوف؟ شفناه سابقًا

في درس أنماط JavaScript شفنا middleware في Express (app.use(logger), app.use(auth))—هذا تطبيق حقيقي لنفس النمط: كل middleware يقرر يعالج الطلب أو يستدعي next() لتمريره للمعالج التالي في السلسلة.

مثال بايثون

class Handler:
    def __init__(self):
        self._next = None

    def set_next(self, handler):
        self._next = handler
        return handler

    def handle(self, request):
        if self._next:
            return self._next.handle(request)
        print("لا يوجد من يعالج الطلب")


class AuthHandler(Handler):
    def handle(self, request):
        if not request.get("token"):
            print("مرفوض: لا يوجد token")
            return
        super().handle(request)


class RateLimitHandler(Handler):
    def handle(self, request):
        if request.get("requests_this_minute", 0) > 100:
            print("مرفوض: تجاوز الحد المسموح")
            return
        super().handle(request)


class LoggerHandler(Handler):
    def handle(self, request):
        print(f"تم قبول الطلب من {request['user']}")
        super().handle(request)


auth = AuthHandler()
rate_limit = RateLimitHandler()
logger = LoggerHandler()
auth.set_next(rate_limit).set_next(logger)

auth.handle({"user": "sara", "token": "abc123", "requests_this_minute": 5})
# تم قبول الطلب من sara

متى تستخدمه؟

  • عندما يمكن لأكثر من كائن معالجة الطلب، والمعالج المناسب يتحدد وقت التشغيل.
  • عندما تريد إصدار طلب لأحد عدة معالجين دون تحديد المستقبِل صراحة في كود العميل.
  • عندما تحتاج إضافة أو إعادة ترتيب معالجين بدون تعديل الكود الموجود (Open/Closed).

⚠️ خطأ شائع: نسيان تمرير الطلب للمعالج التالي (استدعاء next() أو super.handle())، أو عدم وضع معالج افتراضي بنهاية السلسلة—فيضيع الطلب بصمت بدون أي رد.

🎯 التالي: نمط Memento

شرح نمط Chain of Responsibility — أنماط التصميم (Design Patterns) بالعربي
نمط Chain of Responsibilityأنماط التصميم (Design Patterns) بالعربي · The Code Fix

📚 لمزيد من التعمّق في أنماط التصميم (Design Patterns)، راجِع البرمجة الكائنية على ويكيبيديا.

هل كان هذا الدرس مفيدًا؟