الفرق بين المراجعتين ل"Design Patterns/mediator"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
(2.5 محتوى)
(2.6 محتوى)
سطر 120: سطر 120:
 
     // ...
 
     // ...
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
== قابلية الاستخدام ==
 +
* '''استخدم نمط الوسيط عندما يكون من الصعب تغيير بعض الفئات بسبب أن لها ارتباطات كثيرة مع فئات أخرى.'''
 +
يسمح لك النمط باستخراج جميع العلاقات بين الفئات إلى فئة منفصلة عازلًا أي تغييرات على مكون بعينه عن بقية الشيفرة.
 +
* '''استخدم النمط عندما لا تستطيع إعادة استخدام مكون في برنامج مختلف بسبب أنه يعتمد بشدة على مكونات أخرى.'''
 +
تصبح المكونات المنفردة بعد تطبيق نمط الوسيط غير مدركة للمكونات الأخرى رغم أنها تستطيع التواصل بين بعضها البعض -ولو كان بشكل غير مباشر- من خلال كائن وسيط. ولكي تعيد استخدام مكون في برنامج مختلف فإنك تحتاج إلى إضافة فئة وسيط جديدة إليه.
 +
* '''استخدم الوسيط حين تنشئ فئات فرعية كثيرة لمكونات من أجل إعادة استخدام بعض السلوك الأساسي (basic behavior) في سياقات متعددة.'''
 +
بما أن جميع العلاقات بين المكونات محتواة داخل الوسيط، فمن السهل تحديد طرق جديدة كليًا لتعاون تلك المكونات من خلال إدخال فئات وسيط جديدة دون الحاجة إلى تغيير المكونات أنفسها.
 +
 +
== كيفية الاستخدام ==
 +
# حدد مجموعة فئات مرتبطة بشدة ببعضها ستستفيد من كونها مستقلة (من أجل سهولة الصيانة مثلًا أو إعادة استخدام بسيطة لتلك الفئات).
 +
# صرِّح عن واجهة الوسيط وَصِفْ بروتوكول التواصل الذي تريده بين الوسطاء والمكونات الأخرى، ويكفي في أغلب الحالات أسلوب واحد لاستقبال التنبيهات من المكونات. هذه الواجهة ضرورية عندما تريد إعادة استخدام فئات المكونات في سياقات مختلفة، فطالما أن المكون يعمل مع وسيطه من خلال واجهة عامة (generic) فيمكنك ربط ذلك المكون مع استخدام مختلف للوسيط.
 +
# استخدم فئة الوسيط الحقيقية، ستستفيد تلك الفئة من تخزين مراجع إلى كل المكونات التي تديرها.
 +
# تستطيع جعل الوسيط مسؤولًا عن إنشاء وإلغاء كائنات المكوِّن، وعندها قد يتشابه الوسيط مع نمط المصنع المجرد أو الواجهة.
 +
# يجب أن تخزن المكونات مرجعًا إلى كائن الوسيط، ويتم الاتصال غالبًا في منشئ المكون حيث يُمرَّر كائن الوسيط كمُعطى (argument).
 +
# غيِّر شيفرة المكونات بحيث تستدعي أسلوب الإشعار الخاص بالوسيط بدلًا من الأساليب التي في المكونات الأخرى. أيضًا، استخرج الشيفرة التي تضمن استدعاء مكونات أخرى إلى داخل فئة الوسيط، ونفذ هذه الشيفرة كلما استقبل الوسيط إشعارات من ذلك المكون.
 +
 +
== المزايا والعيوب ==
 +
 +
=== المزايا ===
 +
* مبدأ المسؤولية الواحدة. تستطيع استخراج عمليات التواصل بين المكونات المختلفة إلى مكان واحد، مما ييسر استيعابها وصيانتها.
 +
* مبدأ المفتوح/المغلق. تستطيع إدخال وسطاء جدد دون الحاجة إلى تغيير المكونات الحقيقية.
 +
* تستطيع تقليل الارتباط (coupling) بين المكونات المختلفة لبرنامج ما.
 +
* تستطيع إعادة استخدام المكونات المنفردة بشكل أسهل.
 +
 +
=== العيوب ===
 +
* قد يتطور الوسيط مع الوقت إلى كائن إلهي (god object).
 +
 +
== العلاقات مع الأنماط الأخرى ==
 +
تعالج أنماط سلسلة المسؤولية والأمر والوسيط والمراقب طرقًا مختلفة لتوصيل مرسِلات الطلبات ومستقبلاتها ببعضها، وذلك على النحو التالي:
 +
 +
تمرر سلسلة المسؤولية الطلب بشكل تسلسلي مع سلسلة ديناميكية من المستقبلات المحتملة إلى أن يعالجها أحد المستقبلات.
 +
 +
ينشئ الأمر اتصالات أحادية الاتجاه بين المرسِلات والمستقبِلات.
 +
 +
يزيل الوسيط الاتصالات المباشرة بين المرسِلات والمستقبلات مجبرًا إياها على التواصل بشكل غير مباشر من خلال كائن وسيط.
 +
 +
يسمح المراقب للمستقبلات بالاشتراك في استقبال الطلبات وكذلك إلغاء الاشتراك بمرونة.
 +
 +
يتشابه نمطا الواجهة والوسيط في الوظائف، فكلاهما يحاول تنظيم التعاون بين فئات كثيرة مرتبطة ببعضها، وذلك على النحو التالي:
 +
 +
يحدد نمط الواجهة واجهة مبسطة لنظام فرعي من الكائنات، لكنه لا يقدم أي وظيفة جديدة، بل إن النظام الفرعي نفسه غير مدرك لوجود الواجهة، وتستطيع الكائنات داخل النظام الفرعي أن تتواصل بشكل مباشر.
 +
 +
يمركز الوسيط الاتصالات بين مكونات النظام، وتدرك تلك المكونات وجود كائن الوسيط، ولا تتواصل بين بعضها بشكل مباشر.
 +
 +
عادة ما يكونالفرق بين نمطي الوسيط والمراقب محيرًا، ففي أغلب الحالات تستطيع استخدام نمط واحد فحسب منهما، لكن في ظروف تشغيل أخرى قد تستطيع استخدام كليهما معًا، وذلك على النحو التالي:
 +
 +
الهدف الأساسي من الوسيط هو إزالة الاعتماديات المتبادلة (mutual dependencies) بين مجموعة من مكونات النظام، وتصبح تلك المكونات معتمدة على كائن وسيط واحد. أما الهدف من المراقب هو إنشاء اتصالات مرنة أحادية الاتجاه بين الكائنات، حيث تتصرف بعض الكائنات كتوابع لغيرها.
 +
 +
ولدينا استخدام شائع لنمط الوسيط يعتمد فيه على نمط المراقب، يلعب فيه كائن الوسيط دور الناشر (publisher)، ويتصرف كل مكون كمشترك يستطيع الاشتراك في أحداث الوسيط (mediator events) وكذلك إلغاء الاشتراك منها، وتطبيق نمط الوسيط بهذا الشكل يجعله قريب الشبه جدًا من نمط المراقب. تذكر أنك تستطيع استخدام نمط الوسيط بطرق أخرى، فيمكنك مثلًا ربط كل المكونات إلى نفس الكائن الوسيط، ورغم أن هذا الاستخدام لا يشبه نمط المراقب لكن لا يزال صورة من نمط الوسيط.
 +
 +
وتخيل الآن برنامجًا تلعب فيه كل المكونات دور الناشر، سامحة باتصالات مرنة بين بعضها البعض، عندئذ لن يكون هناك كائن وسيط مركزي، بل مجموعة موزعة من المراقبين.
 +
 +
== الاستخدام في لغة جافا ==
 +
 +
== الاستخدام في لغة #C ==
 +
 +
== الاستخدام في لغة PHP ==
 +
 +
== الاستخدام في لغة بايثون ==
 +
 +
== الاستخدام في لغة روبي ==
 +
 +
== الاستخدام في لغة Swift ==
 +
 +
== الاستخدام في لغة TypeScript ==
 +
 +
== انظر أيضًا ==
 +
 +
== مصادر ==

مراجعة 10:05، 22 أغسطس 2019

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

المشكلة

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

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

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

الصورة. قد يكون لديك علاقات كثيرة بين العناصر وبعضها، ومن ثم فإن إجراء تغييرات على بعض العناصر قد يؤثر في غيرها.

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

الحل

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

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

الصورة. عناصر الواجهة الرسومية يجب أن تتواصل بشكل غير مباشر من خلال كائن وسيط.

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

تستطيع المضي في هذا المنطق وتجعل الاعتمادية أكثر مرونة باستخراج الواجهة المشتركة لكل أنواع الصناديق الحوارية، وينبغي أن تصرح الواجهة عن أسلوب الإشعار الذي ستستخدمه كل عناصر الاستمارة لإشعار الصندوق الحواري بالأحداث التي تقع لتلك العناصر، وعليه ينبغي أن يستطيع زر الإرسال الآن أن يعمل مع أي صندوق حواري يستخدم تلك الواجهة. وهكذا يسمح لك نمط الوسيط بتغليف شبكة علاقات بين عدة كائنات داخل كائنِ وسيطٍ واحد، وفائدة هذا أنه كلما قلت الاعتماديات (dependencies) في فئة ما، صار تعديلها أسهل، وكذلك توسيعها وإعادة استخدامها.

مثال من الواقع

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

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

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

البنية

الصورة.

  1. المكونات (Components) هي فئات مختلفة تحتوي على بعض منطق العمل (Business Logic)، وكل مكوّن به مرجع إلى وسيط (mediator)، صُرِّح عنه مع نوع واجهة الوسيط. ولا يشعر المكوّن بفئة الوسيط الحقيقية، لهذا تستطيع إعادة استخدام المكوّن في برامج أخرى من خلال ربطها بوسيط مختلف.
  2. واجهة الوسيط (Mediator) تصرح عن أساليب للتواصل مع المكونات، وتتضمن عادة أسلوب إشعار واحد. وقد تمرر المكونات أي سياق كوسائط (arguments) لهذا الأسلوب، بما في ذلك كائناتها الخاصة، لكن بطريقة لا تسمح بحدوث تكرار بين المكون المستقبِل وفئة المرسِل.
  3. الوسيط الحقيقي (Concrete Mediator) يختزل العلاقات بين المكونات المختلفة، ويحتفظ الوسيط الحقيقي عادة بمراجع إلى كل المكونات التي يديرها، وأحيانًا يدير دورة حياتها كذلك.
  4. يجب ألا تشعر المكونات بوجود المكونات الأخرى، فإن حدث شيء مهم لمكون أو حدث داخله، فيجب أن ينبه الوسيط حصرًا، ويستطيع الوسيط التعرف على المرسل بمجرد استلام الإشعار، وهذا يكون كافيًا في الغالب لتقرير أي مكون يجب أن يُشغَّل في المقابل.

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

مثال وهمي

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

الصورة. هيكل لفئات صندوق حواري في واجهة رسومية.

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

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

// تصرح واجهة الوسيط عن أسلوب تستخدمه المكونات لتنبيه الوسيط بالأحداث
// المختلفة، وقد يتفاعل الوسيط مع تلك الأحداث ويمرر التنفيذ إلى مكونات
// أخرى.
interface Mediator is
    method notify(sender: Component, event: string)


// فئة الوسيط الحقيقي. الشبكة المتداخلة من الاتصالات بين المكونات
// الفردية قد حُلَّت ونُقلت إلى الوسيط.
class AuthenticationDialog implements Mediator is
    private field title: string
    private field loginOrRegisterChkBx: Checkbox
    private field loginUsername, loginPassword: Textbox
    private field registrationUsername, registrationPassword
    private field registrationEmail: Textbox
    private field okBtn, cancelBtn: Button

    constructor AuthenticationDialog() is
        // أنشئ جميع كائنات المكونات ومرر الوسيط الحالي إلى منشئاتها
        // لتحقيق الروابط.

    // حين يحدث شيء ما لمكوِّن ما فإنه ينبه الوسيط، وعندما يستلم الوسيط
    // التنبيه فقد يتصرف بنفسه أو يمرر الطلب إلى مكون آخر.
    method notify(sender, event) is
        if (sender == loginOrRegisterChkBx and event == "check")
            if (loginOrRegisterChkBx.checked)
                title = "Log in"
                // 1. أظهر مكونات استمارة تسجيل الدخول.
                // 2. أخْفِ مكونات استمارة التسجيل.
            else
                title = "Register"
                // 1. أظهر مكونات استمارة تسجيل الدخول.
                // 2. أخْفِ مكونات استمارة التسجيل.

        if (sender == okBtn && event == "click")
            if (loginOrRegister.checked)
                // حاول إيجاد مستخدم عن طريق بيانات تسجيل الدخول.
                if (!found)
                    // أظهر رسالة خطأ فوق حقل تسجيل الدخول.
            else
                // 1. أنشئ حساب مستخدم باستخدام بيانات من حقول التسجيل.
                // 2. سجِّل دخول هذا المستخدم.
                // ...


// تتواصل المكونات مع الوسيط باستخدام واجهة الوسيط.
// ويمكنك استخدام نفس المكونات في سياقات أخرى من خلال
// ربطها بكائنات وسيط مختلفة.
class Component is
    field dialog: Mediator

    constructor Component(dialog) is
        this.dialog = dialog

    method click() is
        dialog.notify(this, "click")

    method keypress() is
        dialog.notify(this, "keypress")

// لا تتواصل المكونات الحقيقية مع بعضها، وليس لها سوى قناة اتصال وحيدة
// وهي إرسال التنبيهات إلى الوسيط.
class Button extends Component is
    // ...

class Textbox extends Component is
    // ...

class Checkbox extends Component is
    method check() is
        dialog.notify(this, "check")
    // ...

قابلية الاستخدام

  • استخدم نمط الوسيط عندما يكون من الصعب تغيير بعض الفئات بسبب أن لها ارتباطات كثيرة مع فئات أخرى.

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

  • استخدم النمط عندما لا تستطيع إعادة استخدام مكون في برنامج مختلف بسبب أنه يعتمد بشدة على مكونات أخرى.

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

  • استخدم الوسيط حين تنشئ فئات فرعية كثيرة لمكونات من أجل إعادة استخدام بعض السلوك الأساسي (basic behavior) في سياقات متعددة.

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

كيفية الاستخدام

  1. حدد مجموعة فئات مرتبطة بشدة ببعضها ستستفيد من كونها مستقلة (من أجل سهولة الصيانة مثلًا أو إعادة استخدام بسيطة لتلك الفئات).
  2. صرِّح عن واجهة الوسيط وَصِفْ بروتوكول التواصل الذي تريده بين الوسطاء والمكونات الأخرى، ويكفي في أغلب الحالات أسلوب واحد لاستقبال التنبيهات من المكونات. هذه الواجهة ضرورية عندما تريد إعادة استخدام فئات المكونات في سياقات مختلفة، فطالما أن المكون يعمل مع وسيطه من خلال واجهة عامة (generic) فيمكنك ربط ذلك المكون مع استخدام مختلف للوسيط.
  3. استخدم فئة الوسيط الحقيقية، ستستفيد تلك الفئة من تخزين مراجع إلى كل المكونات التي تديرها.
  4. تستطيع جعل الوسيط مسؤولًا عن إنشاء وإلغاء كائنات المكوِّن، وعندها قد يتشابه الوسيط مع نمط المصنع المجرد أو الواجهة.
  5. يجب أن تخزن المكونات مرجعًا إلى كائن الوسيط، ويتم الاتصال غالبًا في منشئ المكون حيث يُمرَّر كائن الوسيط كمُعطى (argument).
  6. غيِّر شيفرة المكونات بحيث تستدعي أسلوب الإشعار الخاص بالوسيط بدلًا من الأساليب التي في المكونات الأخرى. أيضًا، استخرج الشيفرة التي تضمن استدعاء مكونات أخرى إلى داخل فئة الوسيط، ونفذ هذه الشيفرة كلما استقبل الوسيط إشعارات من ذلك المكون.

المزايا والعيوب

المزايا

  • مبدأ المسؤولية الواحدة. تستطيع استخراج عمليات التواصل بين المكونات المختلفة إلى مكان واحد، مما ييسر استيعابها وصيانتها.
  • مبدأ المفتوح/المغلق. تستطيع إدخال وسطاء جدد دون الحاجة إلى تغيير المكونات الحقيقية.
  • تستطيع تقليل الارتباط (coupling) بين المكونات المختلفة لبرنامج ما.
  • تستطيع إعادة استخدام المكونات المنفردة بشكل أسهل.

العيوب

  • قد يتطور الوسيط مع الوقت إلى كائن إلهي (god object).

العلاقات مع الأنماط الأخرى

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

تمرر سلسلة المسؤولية الطلب بشكل تسلسلي مع سلسلة ديناميكية من المستقبلات المحتملة إلى أن يعالجها أحد المستقبلات.

ينشئ الأمر اتصالات أحادية الاتجاه بين المرسِلات والمستقبِلات.

يزيل الوسيط الاتصالات المباشرة بين المرسِلات والمستقبلات مجبرًا إياها على التواصل بشكل غير مباشر من خلال كائن وسيط.

يسمح المراقب للمستقبلات بالاشتراك في استقبال الطلبات وكذلك إلغاء الاشتراك بمرونة.

يتشابه نمطا الواجهة والوسيط في الوظائف، فكلاهما يحاول تنظيم التعاون بين فئات كثيرة مرتبطة ببعضها، وذلك على النحو التالي:

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

يمركز الوسيط الاتصالات بين مكونات النظام، وتدرك تلك المكونات وجود كائن الوسيط، ولا تتواصل بين بعضها بشكل مباشر.

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

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

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

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

الاستخدام في لغة جافا

الاستخدام في لغة #C

الاستخدام في لغة PHP

الاستخدام في لغة بايثون

الاستخدام في لغة روبي

الاستخدام في لغة Swift

الاستخدام في لغة TypeScript

انظر أيضًا

مصادر