نمط الزائر ذي الخدمة الفردية
في برمجة الحاسوب ، يُعد نمط الزائر ذو الخدمة الواحدة نمط تصميم . والهدف منه هو تحسين تنفيذ الزائر الذي يتم تخصيصه واستخدامه مرة واحدة فقط ثم حذفه (وهو الحال بالنسبة لمعظم الزوار).
قابلية التطبيق
يُستخدم نمط الزائر ذي الخدمة الواحدة عندما لا يحتاج الزوار إلى البقاء في الذاكرة. وهذا ما يحدث غالبًا عند زيارة تسلسل هرمي من الكائنات (كما هو الحال عند استخدام نمط الزائر مع النمط المركب ) لأداء مهمة واحدة عليه، على سبيل المثال، عدّ عدد الكاميرات في مشهد ثلاثي الأبعاد.
يُستخدم نمط الزائر العادي عندما يجب أن يبقى الزائر في الذاكرة. يحدث هذا عندما يتم تكوين الزائر بعدد من المعلمات التي يجب الاحتفاظ بها في الذاكرة لاستخدامها لاحقًا (على سبيل المثال، لتخزين خيارات العرض لمُعالج عرض المشهد ثلاثي الأبعاد).
مع ذلك، إذا كان ينبغي وجود نسخة واحدة فقط من هذا الزائر في البرنامج بأكمله، فقد يكون من الأفضل تنفيذه كزائر أحادي الاستخدام وككائن أحادي . يضمن هذا إمكانية استدعاء الزائر أحادي الاستخدام لاحقًا مع بقاء معاييره دون تغيير (في هذه الحالة تحديدًا، يُعدّ مصطلح "زائر أحادي الاستخدام" غير دقيق لغويًا، إذ يمكن استخدام الزائر عدة مرات).
أمثلة على الاستخدام
يتم استدعاء الزائر الذي يخدم فرداً واحداً من خلال وسيط من الطرق الثابتة .
بدون معلمات، يكون هذا هو ، بينما مع المعلمات، يكون هو .SingleServingVisitor::applyTo(e);SingleServingVisitor::applyTo(e,a,b);
في حال تم تنفيذه ككائن أحادي:
SingleServingVisitor :: setA ( a ); SingleServingVisitor :: setB ( b ); SingleServingVisitor :: applyTo ( e );عواقب
الإيجابيات
- لا توجد عناصر "زومبي" . مع وجود زائر واحد فقط، يتم ضمان تخصيص الزوار عند الحاجة وتدميرهم بمجرد أن يصبحوا غير مفيدين.
- واجهة أبسط من واجهة الزائر . يتم إنشاء الزائر واستخدامه وتحريره بمجرد استدعاء الدالة
applyTo()الثابتة.
السلبيات
- التخصيص المتكرر . في كل استدعاء للدالة
applyTo()، يتم إنشاء كائن زائر أحادي الخدمة ثم التخلص منه، وهو ما يستغرق وقتًا طويلاً. في المقابل، يقوم الكائن الأحادي بتخصيص واحد فقط.
تطبيق
التنفيذ الأساسي (بدون معلمات)
template < typename A , typename B > class SingleServingVisitor { protected : SingleServingVisitor () = default ; public : ~ SingleServingVisitor () = default ;static void applyTo ( Element & e ) { e . accept ( SingleServingVisitor < A , B > ()); }virtual void visitA ( A & a ) = 0 ; virtual void visitB ( B & b ) = 0 ; };تمرير المعلمات
إذا كان يجب تهيئة الزائر الذي يقدم خدمة واحدة، فيجب تمرير المعلمات من خلال الطريقة الثابتة:
static void applyTo ( Element & elem , const A & a , const B & b ) { elem . accept ( SingleServingVisitor < A , B > ( a , b )); }التنفيذ ككائن أحادي
يضمن هذا التطبيق ما يلي:
- أنه لا يوجد على الأكثر حالة واحدة للزائر الذي يقدم خدمة واحدة فقط.
- أن الزائر يمكن الوصول إليه لاحقًا
template < typename A , typename B > class SingleServingVisitor { protected : A a ; B b ;SingleServingVisitor () = default ;// ملاحظة: لا يشترط أن تكون دالة instance() عامة. static SingleServingVisitor & instance () noexcept { static SingleServingVisitor ssv ; return ssv ; } public : ~ SingleServingVisitor () = default ;static void applyTo ( Element & e ) noexcept { e . accept ( instance ()); }// طرق ثابتة للوصول إلى المعاملات static void setA ( const A & a ) noexcept { this -> a = a ; }static void setB ( const B & b ) noexcept { this -> b = b ; }virtual void visitA ( A & a ) = 0 ; virtual void visitB ( B & b ) = 0 ; };أنماط ذات صلة
- نمط الزائر ، الذي يستمد منه هذا النمط
- نمط التركيب : غالبًا ما يتم تطبيق نمط الزائر ذي الخدمة الواحدة على التسلسلات الهرمية للعناصر
- نمط فردي
- أنماط تصميم البرمجيات
