1. ما هو نمط سلسلة القيمة

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

2. الخصائص والمزايا لنمط سلسلة القيمة

الخصائص والمزايا لنمط سلسلة القيمة كما يلي:

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

3. أمثلة لتطبيقات نمط سلسلة القيمة العملية

نمط سلسلة القيمة له العديد من التطبيقات العملية، مثل:

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

4. تنفيذ نمط سلسلة القيمة في جولانج

4.1 الرسم البياني UML للفئات

نمط سلسلة القيمة في جولانج

4.2 مقدمة المثال

في الرسم البياني UML أعلاه، قمنا بتعريف معالج محدد (Handler) ومعالجين محددين ملموسين (ConcreteHandler1 وConcreteHandler2). يقوم العميل (Client) ببدء الطلبات بالاتصال بطريقة handleRequest للمعالج.

4.3 خطوة تنفيذ 1: تعريف واجهة المعالج المحدد

type Handler interface {
    HandleRequest(request Request) error
    SetNext(handler Handler)
}

type Request interface {
    Condition bool
}

تعريف واجهة المعالج المحدد يحدد الطريقة HandleRequest لمعالجة الطلبات والطريقة SetNext لضبط المعالج التالي.

4.4 خطوة تنفيذ 2: تنفيذ فئات المعالجات المحددة

type ConcreteHandler1 struct {
    next Handler
}

func (h *ConcreteHandler1) HandleRequest(request Request) error {
    // منطق معالجة الطلب
    if request.Condition {
        // الكود لمعالجة الطلب
        return nil
    } else {
        if h.next != nil {
            return h.next.HandleRequest(request)
        }
        return errors.New("لم يتم العثور على معالج")
    }
}

func (h *ConcreteHandler1) SetNext(handler Handler) {
    h.next = handler
}

type ConcreteHandler2 struct {
    next Handler
}

func (h *ConcreteHandler2) HandleRequest(request Request) error {
    // منطق معالجة الطلب
    if request.Condition {
        // الكود لمعالجة الطلب
        return nil
    } else {
        if h.next != nil {
            return h.next.HandleRequest(request)
        }
        return errors.New("لم يتم العثور على معالج")
    }
}

func (h *ConcreteHandler2) SetNext(handler Handler) {
    h.next = handler
}

تنفيذ فئات المعالجات المحددة بتنفيذ واجهة المعالج المحدد وتجاوز طرق HandleRequest وSetNext.

4.5 خطوة تنفيذ 3: بناء سلسلة القيمة العملية

handler1 := &ConcreteHandler1{}
handler2 := &ConcreteHandler2{}

handler1.SetNext(handler2)

من خلال إنشاء معالجات محددة وضبط المعالج التالي، يتم بناء سلسلة المسؤولية.

4.6 خطوة تنفيذ 4: كود العميل

func main() {
    handler := &ConcreteHandler1{}

    // بناء سلسلة المسؤولية
    handler.SetNext(&ConcreteHandler2{})

    // إرسال طلب
    handler.HandleRequest(Request{Condition: true})
}

في كود العميل، يتم إنشاء معالج محدد، ويتم ضبط المعالج التالي، ثم يتم استدعاء طريقة HandleRequest لإرسال طلب.