نمط الأمر

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

هناك أربعة مصطلحات ترتبط دائمًا بنمط الأوامر وهي: command و receiver و invoker و client . يعرف كائن الأمر عن المتلقي ويستدعي طريقة للمتلقي. يتم تخزين قيم معلمات طريقة المتلقي في الأمر. يتم أيضًا تخزين كائن المتلقي لتنفيذ هذه الطرق في كائن الأمر عن طريق التجميع . ثم يقوم المتلقي بالعمل عند استدعاء execute()الطريقة في الأمر . يعرف كائن المستدعي كيفية تنفيذ الأمر، ويقوم بشكل اختياري بالمحاسبة حول تنفيذ الأمر. لا يعرف المستدعي أي شيء عن أمر ملموس، فهو يعرف فقط واجهة الأمر . يتم الاحتفاظ بكائنات المستدعي وكائنات الأمر وكائنات المستقبل بواسطة كائن العميل . يقرر العميل أي كائنات المستقبل يقوم بتعيينها لكائنات الأمر، وأي الأوامر يقوم بتعيينها للمستدعي. يقرر العميل أي الأوامر يتم تنفيذها عند أي نقطة. لتنفيذ أمر، فإنه يمرر كائن الأمر إلى كائن المستدعي.

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

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

ملخص

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

يمكن حل هذه المشاكل باستخدام نمط تصميم الأوامر: [2]

  • يجب تجنب ربط المستدعي لطلب بطلب معين. أي أنه يجب تجنب الطلبات المبرمجة مسبقًا.
  • يجب أن يكون من الممكن تكوين كائن (يستدعي طلبًا) باستخدام طلب.

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

يؤدي استخدام نمط تصميم الأوامر إلى وصف الحل التالي:

  • قم بتعريف كائنات (أمر) منفصلة تغلف الطلب.
  • تقوم الفئة بتفويض طلب إلى كائن أمر بدلاً من تنفيذ طلب معين بشكل مباشر.

يتيح هذا تكوين فئة باستخدام كائن أمر يستخدم لتنفيذ طلب. لم تعد الفئة مقترنة بطلب معين ولا تمتلك أي معرفة (مستقلة) بكيفية تنفيذ الطلب.

انظر أيضًا إلى مخطط فئة UML وتسلسلها أدناه.

بناء

مخطط فئة وتسلسل UML

مثال لفئة UML ومخطط التسلسل لنمط تصميم Command. [3]

في مخطط فئة UML أعلاه ، لا تنفذ الفئة طلبًا بشكل مباشر. بدلاً من ذلك، تشير إلى الواجهة لأداء الطلب ( )، مما يجعلها مستقلة عن كيفية أداء الطلب. تنفذ الفئة الواجهة من خلال تنفيذ إجراء على جهاز استقبال ( ). InvokerInvokerCommandcommand.execute()InvokerCommand1Commandreceiver1.action1()

يوضح مخطط تسلسل UML التفاعلات التي تحدث أثناء وقت التشغيل: يستدعي الكائن كائنًا ، ويستدعي كائنًا ، والذي يقوم بتنفيذ الطلب. Invokerexecute()Command1Command1action1()Receiver1

مخطط فئة UML

مخطط UML لنمط الأوامر

الاستخدامات

أزرار واجهة المستخدم الرسومية وعناصر القائمة
في برمجة Swing و Borland DelphiAction ، يعد an كائن أمر. بالإضافة إلى القدرة على تنفيذ الأمر المطلوب، قد يكون للإجراء أيقونة مرتبطة به، واختصار لوحة مفاتيح، ونص إرشادي، وما إلى ذلك. يمكن تهيئة زر شريط الأدوات أو مكون عنصر القائمة بالكامل باستخدام كائن الإجراء فقط .
تسجيل الماكرو
إذا تم تمثيل جميع إجراءات المستخدم بواسطة كائنات الأوامر، فيمكن للبرنامج تسجيل سلسلة من الإجراءات ببساطة عن طريق الاحتفاظ بقائمة من كائنات الأوامر أثناء تنفيذها. ثم يمكنه "إعادة تشغيل" نفس الإجراءات عن طريق تنفيذ نفس كائنات الأوامر مرة أخرى بالتسلسل. إذا قام البرنامج بتضمين محرك نصوص برمجية، فيمكن لكل كائن أمر تنفيذ طريقة toScript() ، ومن ثم يمكن تسجيل إجراءات المستخدم بسهولة كنصوص برمجية.
كود الجوال
باستخدام لغات مثل Java حيث يمكن دفق/امتصاص الكود من موقع إلى آخر عبر URLClassloaders وCodebases، يمكن للأوامر تمكين توصيل سلوك جديد إلى مواقع بعيدة (أمر EJB، Master Worker).
التراجع متعدد المستويات
إذا تم تنفيذ جميع إجراءات المستخدم في برنامج ما ككائنات أوامر، فيمكن للبرنامج الاحتفاظ بمجموعة من الأوامر التي تم تنفيذها مؤخرًا. عندما يريد المستخدم التراجع عن أمر ما، يقوم البرنامج ببساطة بإخراج كائن الأمر الأحدث وتنفيذ طريقة التراجع الخاصة به .
الشبكات
من الممكن إرسال كائنات الأوامر بأكملها عبر الشبكة ليتم تنفيذها على الأجهزة الأخرى، على سبيل المثال تصرفات اللاعب في ألعاب الكمبيوتر.
المعالجة المتوازية
حيث تتم كتابة الأوامر كمهام إلى مورد مشترك وتنفيذها بواسطة العديد من الخيوط بالتوازي (ربما على أجهزة بعيدة؛ غالبًا ما يشار إلى هذا المتغير باسم نمط السيد/العامل)
أشرطة التقدم
لنفترض أن أحد البرامج يحتوي على سلسلة من الأوامر التي ينفذها بالترتيب. إذا كان لكل كائن أمر طريقة getEstimatedDuration() ، فيمكن للبرنامج بسهولة تقدير المدة الإجمالية. ويمكنه عرض شريط تقدم يعكس بشكل مفيد مدى اقتراب البرنامج من إكمال جميع المهام.
مجموعات الخيوط
قد تحتوي فئة تجمع الخيوط العامة النموذجية على طريقة addTask() عامة تضيف عنصر عمل إلى قائمة انتظار داخلية للمهام التي تنتظر الانتهاء منها. وهي تحافظ على مجموعة من الخيوط التي تنفذ الأوامر من قائمة الانتظار. العناصر الموجودة في قائمة الانتظار هي كائنات أوامر. عادةً ما تنفذ هذه الكائنات واجهة مشتركة مثل java.lang.Runnable التي تسمح لمجموعة الخيوط بتنفيذ الأمر حتى لو تم كتابة فئة تجمع الخيوط نفسها دون أي معرفة بالمهام المحددة التي سيتم استخدامها من أجلها.
السلوك المعاملاتي
على غرار التراجع، قد يحتفظ محرك قاعدة البيانات أو مثبت البرامج بقائمة بالعمليات التي تم إجراؤها أو سيتم إجراؤها. في حالة فشل أحدها، يمكن عكس جميع العمليات الأخرى أو تجاهلها (عادةً ما يُطلق عليها التراجع ). على سبيل المثال، إذا كان لا بد من تحديث جدولين لقاعدة البيانات يشيران إلى بعضهما البعض، وفشل التحديث الثاني، فيمكن التراجع عن المعاملة، بحيث لا يحتوي الجدول الأول الآن على مرجع غير صالح.
السحرة
غالبًا ما يعرض المعالج عدة صفحات من التكوين لإجراء واحد يحدث فقط عندما ينقر المستخدم على زر "إنهاء" في الصفحة الأخيرة. في هذه الحالات، الطريقة الطبيعية لفصل كود واجهة المستخدم عن كود التطبيق هي تنفيذ المعالج باستخدام كائن الأمر. يتم إنشاء كائن الأمر عند عرض المعالج لأول مرة. تخزن كل صفحة معالج تغييرات واجهة المستخدم الرسومية الخاصة بها في كائن الأمر، لذلك يتم ملء الكائن مع تقدم المستخدم. يؤدي "إنهاء" ببساطة إلى تشغيل استدعاء execute() . بهذه الطريقة، ستعمل فئة الأمر.

مصطلحات

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

  1. الغموض.
    1. إن مصطلح الأمر غامض. على سبيل المثال، قد يشير move up, move up إلى أمر واحد (move up) يجب تنفيذه مرتين، أو قد يشير إلى أمرين، يحدث أن يقوم كل منهما بنفس الشيء (move up). إذا تمت إضافة الأمر السابق مرتين إلى مكدس التراجع، فإن كلا العنصرين في المكدس يشيران إلى نفس مثيل الأمر. قد يكون هذا مناسبًا عندما يمكن دائمًا التراجع عن أمر بنفس الطريقة (على سبيل المثال move down). يستخدم كل من Gang of Four ومثال Java أدناه هذا التفسير لمصطلح الأمر . من ناحية أخرى، إذا تمت إضافة الأوامر الأخيرة إلى مكدس التراجع، فإن المكدس يشير إلى كائنين منفصلين. قد يكون هذا مناسبًا عندما يجب أن يحتوي كل كائن في المكدس على معلومات تسمح بالتراجع عن الأمر. على سبيل المثال، للتراجع عن أمر حذف التحديد ، قد يحتوي الكائن على نسخة من النص المحذوف بحيث يمكن إعادة إدراجه، إذا كان يجب التراجع عن أمر حذف التحديد . لاحظ أن استخدام كائن منفصل لكل استدعاء لأمر هو أيضًا مثال على نمط سلسلة المسؤولية .
    2. إن مصطلح "تنفيذ" غامض أيضًا. فقد يشير إلى تشغيل التعليمات البرمجية التي تم تحديدها بواسطة طريقة التنفيذ الخاصة بكائن الأمر. ومع ذلك، في Windows Presentation Foundation من Microsoft ، يُعتبر الأمر قد تم تنفيذه عند استدعاء طريقة تنفيذ الأمر ، ولكن هذا لا يعني بالضرورة أن تعليمات برمجية التطبيق قد تم تشغيلها. يحدث هذا فقط بعد معالجة حدث آخر.
  2. المرادفات والمتجانسات .
    1. العميل، المصدر، المستدعي : الزر، أو زر شريط الأدوات، أو عنصر القائمة الذي تم النقر عليه، أو مفتاح الاختصار الذي ضغط عليه المستخدم.
    2. كائن الأمر، كائن الأمر الموجه، كائن الإجراء : كائن مفرد (على سبيل المثال، يوجد CopyCommandكائن واحد فقط)، يعرف مفاتيح الاختصار، وصور الأزرار، ونص الأمر، وما إلى ذلك المتعلقة بالأمر. يستدعي كائن المصدر أو المستدعي طريقة execute أو performAction الخاصة بكائن الأمر أو الإجراء. يخطر كائن الأمر/الإجراء كائنات المصدر/المستدعي المناسبة عندما يتغير توفر أمر/إجراء. يسمح هذا للأزرار وعناصر القائمة بأن تصبح غير نشطة (رمادية اللون) عندما لا يمكن تنفيذ أمر/إجراء.
    3. المستقبل، الكائن المستهدف : الكائن الذي سيتم نسخه أو لصقه أو نقله وما إلى ذلك. يمتلك كائن المستقبل الطريقة التي يتم استدعاؤها بواسطة طريقة تنفيذ الأمر . عادةً ما يكون المستقبل أيضًا الكائن المستهدف. على سبيل المثال، إذا كان كائن المستقبل عبارة عن مؤشر وتم استدعاء الطريقة moveUp، فمن المتوقع أن يكون المؤشر هو هدف الإجراء moveUp. من ناحية أخرى، إذا تم تعريف الكود بواسطة كائن الأمر نفسه، فسيكون الكائن المستهدف كائنًا مختلفًا تمامًا.
    4. كائن الأمر، حجج الأحداث الموجهة، كائن الحدث : الكائن الذي يتم تمريره من المصدر إلى كائن الأمر/الإجراء، إلى كائن الهدف إلى الكود الذي يقوم بالعمل. كل نقرة زر أو مفتاح اختصار ينتج عنه كائن أمر/حدث جديد. تضيف بعض التطبيقات مزيدًا من المعلومات إلى كائن الأمر/الحدث أثناء تمريره من كائن (مثلًا CopyCommand) إلى آخر (مثل قسم المستند). تضع تطبيقات أخرى كائنات الأمر/الحدث في كائنات حدث أخرى (مثل مربع داخل مربع أكبر) أثناء تحركها على طول الخط، لتجنب تعارضات التسمية. (انظر أيضًا نمط سلسلة المسؤولية .)
    5. المعالج ExecutedRoutedEventHandler، الطريقة، الوظيفة : الكود الفعلي الذي يقوم بالنسخ واللصق والنقل وما إلى ذلك. في بعض التطبيقات يكون كود المعالج جزءًا من كائن الأمر/الإجراء. وفي تطبيقات أخرى يكون الكود جزءًا من كائن المستقبل/الهدف، وفي تطبيقات أخرى يتم الاحتفاظ بكود المعالج منفصلاً عن الكائنات الأخرى.
    6. مدير الأوامر، مدير التراجع، المجدول، قائمة الانتظار، المرسل، المستدعي : كائن يضع كائنات الأوامر/الأحداث على مكدس التراجع أو مكدس الإعادة، أو يحتفظ بكائنات الأوامر/الأحداث حتى تصبح كائنات أخرى جاهزة للعمل عليها، أو يوجه كائنات الأوامر/الأحداث إلى كائن المستقبل/الهدف المناسب أو كود المعالج.
  3. تنفيذات تتجاوز نمط الأوامر الأصلي بشكل كبير.
    1. يقدم Windows Presentation Foundation (WPF) من Microsoft أوامر موجهة، والتي تجمع بين نمط الأوامر ومعالجة الأحداث. ونتيجة لذلك، لم يعد كائن الأمر يحتوي على مرجع إلى الكائن المستهدف ولا مرجع إلى كود التطبيق. بدلاً من ذلك، يؤدي استدعاء أمر execute الخاص بكائن الأمر إلى ما يسمى بـ Executed Routed Event والذي قد يواجه أثناء نفق الحدث أو فقاعاته ما يسمى بـ binding object الذي يحدد الهدف وكود التطبيق، والذي يتم تنفيذه في تلك النقطة.

مثال

يعتمد تنفيذ C++14 هذا على التنفيذ السابق لـ C++98 الموجود في الكتاب.

#تضمين <iostream> #تضمين <الذاكرة> 
 

class Command { public : // يعلن عن واجهة لتنفيذ عملية. virtual void execute () = 0 ; virtual ~ Command () = default ; protected : Command () = default ; };  

  
      
     

    


template < typename Receiver > class SimpleCommand : public Command { // ConcreteCommand public : typedef void ( Receiver ::* Action )(); // يحدد ارتباطًا بين كائن Receiver و action. SimpleCommand ( std :: shared_ptr < Receiver > receiver_ , Action action_ ) : receiver ( receiver_ . get ()), action ( action_ ) { } SimpleCommand ( const SimpleCommand & ) = delete ; // قاعدة الثلاثة const SimpleCommand & operator = ( const SimpleCommand & ) = delete ; // ينفذ execute عن طريق استدعاء العملية (العمليات) المقابلة على Receiver. virtual void execute () { ( receiver ->* action )(); } private : Receiver * receiver ; Action action ; };  
      

     
  
      
       
      
       
  
     
    
  

   
   


class MyClass { // Receiver public : // تعرف كيفية تنفيذ العمليات المرتبطة بتنفيذ الطلب. يمكن لأي فئة أن تعمل كمستقبل. void action () { std :: cout << "MyClass::action \n " ; } };   

  
    
      
  


int main () { // تمنع المؤشرات الذكية تسرب الذاكرة. std :: shared_ptr < MyClass > receiver = std :: make_shared < MyClass > (); // ... std :: unique_ptr < Command > command = std :: make_unique < SimpleCommand < MyClass > ( receiver , & MyClass :: action ); // ... command -> execute ( ); }  
  
     
  
       
  
  

مخرجات البرنامج هي

MyClass :: العمل

انظر أيضا

تاريخ

يبدو أن أول ذكر منشور لاستخدام فئة Command لتنفيذ أنظمة تفاعلية كان في مقالة عام 1985 بقلم هنري ليبرمان. [4] يبدو أن أول وصف منشور لآلية التراجع والإعادة (متعددة المستويات)، باستخدام فئة Command مع طرق التنفيذ والتراجع وقائمة التاريخ، هو الطبعة الأولى (1988) من كتاب برتراند ماير " إنشاء البرمجيات الموجهة للكائنات" ، [5] القسم 12.2.

مراجع

  1. ^ إيريك جاما؛ ريتشارد هيلم؛ رالف جونسون؛ جون فليسيدس (1994). أنماط التصميم: عناصر البرمجيات الموجهة للكائنات القابلة لإعادة الاستخدام . أديسون ويسلي. ص 233 وما يليه. رقم ISBN 0-201-63361-2.
  2. ^ "نمط تصميم الأمر - المشكلة والحل والتطبيق". w3sDesign.com . مؤرشف من الأصل في 2020-09-23 . تم الاسترجاع 2017-08-12 .
  3. ^ "نمط تصميم الأوامر - الهيكل والتعاون". w3sDesign.com . تم الاسترجاع في 2017-08-12 .[ رابط معطل ]
  4. ^ ليبرمان، هنري (1985). "توجد في أنظمة القوائم أشياء أكثر من تلك التي تظهر على الشاشة". ACM SIGGRAPH Computer Graphics . 19 (3): 181–189. doi :10.1145/325165.325235.
  5. ^ ماير، برتراند (1988). بناء البرمجيات الموجهة للكائنات (الطبعة الأولى). برنتيس هول.
  • نمط الأمر
  • نصيحة Java 68: تعلم كيفية تنفيذ نمط الأوامر في Java
تم الاسترجاع من "https://en.wikipedia.org/w/index.php?title=نمط_الأوامر&oldid=1240195490"
Original text
Rate this translation
Your feedback will be used to help improve Google Translate