कमांड पैटर्न

ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग में, कमांड पैटर्न एक  व्यवहार पैटर्न  डिज़ाइन पैटर्न (कंप्यूटर विज्ञान) है जिसमें एक ऑब्जेक्ट का उपयोग किसी क्रिया को करने या बाद में किसी घटना को ट्रिगर करने के लिए आवश्यक सभी सूचनाओं को छिपाने के लिए किया जाता है। इस जानकारी में विधि का नाम, विधि का स्वामित्व ऑब्जेक्ट और विधि पैरामीटर के मान सम्मिलित हैं।

कमांड पैटर्न से सदैव जुड़े चार शब्द 'कमांड', 'प्राप्तकर्ता', 'आह्वानकर्ता' और 'क्लाइंट' हैं। एक 'कमांड' ऑब्जेक्ट 'प्राप्तकर्ता' के विषय में जानता है और प्राप्तकर्ता की एक विधि को आमंत्रित करता है। प्राप्तकर्ता विधि के मापदंडों के मान कमांड में संग्रहीत हैं। इन विधियों को निष्पादित करने के लिए प्राप्तकर्ता ऑब्जेक्ट को  एकत्रीकरण द्वारा कमांड ऑब्जेक्ट में भी संग्रहीत किया जाता है। 'प्राप्तकर्ता' तब कार्य  करता है जब   मेथड इन कमांड कहा जाता है। एक आह्वानकर्ता ऑब्जेक्ट जानता है कि कमांड को कैसे निष्पादित किया जाए, और वैकल्पिक रूप से कमांड निष्पादन के विषय  में बहीखाता पद्धति करता है। आह्वानकर्ता को ठोस कमांड के विषय  में कुछ नहीं पता होता है, वह केवल कमांड इंटरफेस के विषय  में जानता है। आह्वानकर्ता ऑब्जेक्ट (ओं), कमांड ऑब्जेक्ट्स और प्राप्तकर्ता ऑब्जेक्ट्स क्लाइंट ऑब्जेक्ट द्वारा आयोजित किए जाते हैं, क्लाइंट यह तय करता है कि वह कौन सी प्राप्तकर्ता ऑब्जेक्ट्स कमांड ऑब्जेक्ट्स को असाइन करता है, और कौन सी कमांड्स आह्वानकर्ता को असाइन करता है। क्लाइंट तय करता है कि कौन से कमांड को किस बिंदु पर निष्पादित करना है। कमांड को निष्पादित करने के लिए, यह कमांड ऑब्जेक्ट को आह्वानकर्ता ऑब्जेक्ट को पास करता है।

कमांड ऑब्जेक्ट्स का उपयोग करना सामान्य घटकों का निर्माण करना सरल बनाता है जिन्हें विधि या विधि पैरामीटर के वर्ग को जानने की आवश्यकता के बिना उनके चयन के समय विधि कॉल को प्रतिनिधि, अनुक्रम या निष्पादित करने की आवश्यकता होती है। एक आह्वानकर्ता ऑब्जेक्ट का उपयोग करने से कमांड निष्पादन के विषय  में बहीखाता पद्धति को आसानी से निष्पादित किया जा सकता है, साथ ही साथ कमांड के लिए अलग-अलग मोड लागू किए जा सकते हैं, जो कि आह्वानकर्ता ऑब्जेक्ट द्वारा प्रबंधित किए जाते हैं, क्लाइंट को बहीखाता पद्धति या मोड के अस्तित्व के विषय  में पता होने की आवश्यकता के बिना।

इस डिजाइन पैटर्न के केंद्रीय विचार कार्यात्मक प्रोग्रामिंग भाषाओं में प्रथम श्रेणी के कार्यों और उच्च-क्रम के कार्यों के शब्दार्थों को बारीकी से प्रतिबिंबित करते हैं। विशेष रूप से, आह्वानकर्ता ऑब्जेक्ट एक उच्च-क्रम का कार्य है जिसमें कमांड ऑब्जेक्ट प्रथम श्रेणी का तर्क है।

सिंहावलोकन
आदेश डिजाइन पैटर्न्स तेईस प्रसिद्ध डिज़ाइन पैटर्न में से एक है जो वर्णन करता है कि लचीले और पुन: प्रयोज्य ऑब्जेक्ट-ओरिएंटेड सॉफ़्टवेयर को डिज़ाइन करने के लिए आवर्ती डिज़ाइन समस्याओं को कैसे हल किया जाए, अर्थात ऐसी वस्तुएँ जिन्हें लागू करना, बदलना, परीक्षण करना और पुन: उपयोग करना सरल हो।

कमांड डिज़ाइन पैटर्न का उपयोग करके इन समस्याओं को हल किया जा सकता है:
 * किसी अनुरोध के आह्वानकर्ता को किसी विशेष अनुरोध से जोड़ने से बचना चाहिए। यानी हार्ड-वायर्ड अनुरोधों से बचना चाहिए।
 * एक अनुरोध के साथ एक ऑब्जेक्ट (जो एक अनुरोध का आह्वान करती है) को कॉन्फ़िगर करना संभव होना चाहिए।

एक वर्ग में सीधे एक अनुरोध को लागू करना (हार्ड-वायरिंग) अनम्य है क्योंकि यह कक्षा को संकलन-समय पर एक विशेष अनुरोध से जोड़ता है, जिससे रन-टाइम पर एक अनुरोध निर्दिष्ट करना असंभव हो जाता है।

कमांड डिजाइन पैटर्न का प्रयोग निम्नलिखित समाधान का वर्णन करता है:


 * अलग (कमांड) ऑब्जेक्ट्स को परिभाषित करें जो एक अनुरोध को एनकैप्सुलेट करते हैं।
 * एक वर्ग सीधे किसी विशेष अनुरोध को लागू करने के बजाय कमांड ऑब्जेक्ट के लिए अनुरोध करता है।

यह एक वर्ग को कमांड ऑब्जेक्ट के साथ कॉन्फ़िगर करने में सक्षम बनाता है जिसका उपयोग अनुरोध करने के लिए किया जाता है। कक्षा अब किसी विशेष अनुरोध से जुड़ी नहीं है और अनुरोध कैसे किया जाता है इसका कोई ज्ञान नहीं है (स्वतंत्र है)।

नीचे यूएमएल क्लास और सीक्वेंस डायग्राम भी देखें।

यूएमएल वर्ग और अनुक्रम आरेख
उपरोक्त एकीकृत मॉडलिंग भाषा   वर्ग आरेख  में,   वर्ग सीधे अनुरोध को लागू नहीं करता है। बजाय,  यह आपकी जानकारी के लिए है   अनुरोध करने के लिए इंटरफ़ेस, जो बनाता है   अनुरोध कैसे किया जाता है इससे स्वतंत्र।   e> वर्ग लागू करता है   एक प्राप्तकर्ता पर एक क्रिया करके इंटरफ़ेस. एकीकृत मॉडलिंग भाषा अनुक्रम आरेख रन-टाइम इंटरैक्शन दिखाता है:  ई> ऑब्जेक्ट कॉल   एक पर   वस्तु। कॉल  एक पर   वस्तु, जो अनुरोध करता है।

उपयोग करता है

 * जीयूआई बटन और मेनू आइटम: स्विंग (जावा) और बोरलैंड डेल्फी प्रोग्रामिंग में, ए एक कमांड ऑब्जेक्ट है। वांछित आदेश को निष्पादित करने की क्षमता के अतिरिक्त, a Action में संबद्ध चिह्न, कुँजीपटल शॉर्टकट, टूलटिप पाठ, इत्यादि हो सकते हैं। टूलबार बटन या मेनू आइटम घटक को केवल का उपयोग करके पूरी तरह से प्रारंभ किया जा सकता है Action वस्तु।
 * मैक्रो (कंप्यूटर विज्ञान) रिकॉर्डिंग: यदि सभी उपयोगकर्ता क्रियाएं कमांड ऑब्जेक्ट्स द्वारा दर्शाई जाती हैं, तो एक प्रोग्राम केवल कमांड ऑब्जेक्ट्स की सूची को क्रियान्वित करते हुए क्रियाओं के अनुक्रम को रिकॉर्ड कर सकता है। यह फिर उसी कमांड ऑब्जेक्ट को क्रम में फिर से निष्पादित करके उसी क्रिया को वापस चला सकता है। यदि प्रोग्राम एक स्क्रिप्टिंग इंजन को एम्बेड करता है, तो प्रत्येक कमांड ऑब्जेक्ट एक को लागू कर सकता है toScript विधि, और फिर उपयोगकर्ता क्रियाओं को स्क्रिप्ट के रूप में आसानी से रिकॉर्ड किया जा सकता है।
 * कोड गतिशीलता: जावा जैसी भाषाओं का उपयोग करना जहां कोड को एक स्थान से दूसरे स्थान पर URLClassloaders और Codebases के माध्यम से प्रवाहित/स्लिप किया जा सकता है, कमांड नए व्यवहार को दूरस्थ स्थानों (EJB कमांड, मास्टर वर्कर) तक पहुंचाने में सक्षम बना सकते हैं।
 * मल्टी-लेवल अनडू : यदि किसी प्रोग्राम में सभी उपयोगकर्ता क्रियाएं कमांड ऑब्जेक्ट के रूप में लागू की जाती हैं, तो प्रोग्राम हाल ही में निष्पादित कमांड का ढेर रख सकता है। जब उपयोगकर्ता कमांड को पूर्ववत करना चाहता है, तो प्रोग्राम केवल सबसे हालिया कमांड ऑब्जेक्ट को पॉप करता है और इसे निष्पादित करता है undo तरीका।
 * नेटवर्किंग: अन्य मशीनों पर निष्पादित होने के लिए पूरे नेटवर्क में पूरे कमांड ऑब्जेक्ट को भेजना संभव है, उदाहरण के लिए कंप्यूटर गेम में प्लेयर एक्शन।
 * समानांतर प्रसंस्करण: जहां आदेशों को एक साझा संसाधन के कार्यों के रूप में लिखा जाता है और समानांतर में कई थ्रेड्स द्वारा निष्पादित किया जाता है (संभवतः दूरस्थ मशीनों पर; इस संस्करण को अक्सर मास्टर/वर्कर पैटर्न के रूप में संदर्भित किया जाता है)
 * प्रगति पट्टियाँ: मान लीजिए कि किसी प्रोग्राम में आदेशों का एक क्रम है जिसे वह क्रम में निष्पादित करता है। यदि प्रत्येक कमांड ऑब्जेक्ट में a getEstimatedDuration विधि, कार्यक्रम आसानी से कुल अवधि का अनुमान लगा सकता है। यह एक प्रगति बार दिखा सकता है जो सार्थक रूप से दर्शाता है कि कार्यक्रम सभी कार्यों को पूरा करने के कितने करीब है।
 * धागा पूल : एक विशिष्ट, सामान्य-उद्देश्य वाले थ्रेड पूल वर्ग में एक सार्वजनिक हो सकता है addTask विधि जो कार्य आइटम को किए जाने की प्रतीक्षा कर रहे कार्यों की आंतरिक कतार में जोड़ती है। यह थ्रेड्स का एक पूल बनाए रखता है जो कतार से कमांड निष्पादित करता है। कतार में आइटम कमांड ऑब्जेक्ट हैं। आमतौर पर ये वस्तुएं एक सामान्य इंटरफ़ेस को लागू करती हैं जैसे java.lang.Runnable जो थ्रेड पूल को कमांड निष्पादित करने की अनुमति देता है, भले ही थ्रेड पूल क्लास को विशिष्ट कार्यों के ज्ञान के बिना लिखा गया हो जिसके लिए इसका उपयोग किया जाएगा।
 * डेटाबेस लेन-देन व्यवहार: पूर्ववत के समान, एक डेटाबेस इंजन या सॉफ़्टवेयर इंस्टॉलर संचालन की एक सूची रख सकता है जो किया गया है या किया जाएगा। अगर उनमें से एक विफल हो जाता है, तो अन्य सभी को उलटा या त्याग दिया जा सकता है (आमतौर पर रोलबैक कहा जाता है)। उदाहरण के लिए, यदि दो डेटाबेस तालिकाएँ जो एक दूसरे को संदर्भित करती हैं, को अद्यतन किया जाना चाहिए, और दूसरा अद्यतन विफल हो जाता है, तो लेन-देन को वापस ले लिया जा सकता है, ताकि पहली तालिका में अब कोई अमान्य संदर्भ न हो।
 * विज़ार्ड (सॉफ़्टवेयर) एस: अक्सर एक विज़ार्ड एक ही क्रिया के लिए कॉन्फ़िगरेशन के कई पृष्ठ प्रस्तुत करता है जो तब होता है जब उपयोगकर्ता अंतिम पृष्ठ पर फिनिश बटन पर क्लिक करता है। इन मामलों में, उपयोगकर्ता इंटरफ़ेस कोड को एप्लिकेशन कोड से अलग करने का एक प्राकृतिक तरीका कमांड ऑब्जेक्ट का उपयोग करके विज़ार्ड को लागू करना है। विज़ार्ड पहली बार प्रदर्शित होने पर कमांड ऑब्जेक्ट बनाया जाता है। प्रत्येक विज़ार्ड पृष्ठ कमांड ऑब्जेक्ट में अपने जीयूआई परिवर्तन संग्रहीत करता है, इसलिए उपयोगकर्ता की प्रगति के रूप में ऑब्जेक्ट पॉप्युलेट हो जाता है। समाप्त बस कॉल को ट्रिगर करता है execute. इस तरह, कमांड क्लास कार्य करेगी।

शब्दावली
कमांड पैटर्न कार्यान्वयन का वर्णन करने के लिए प्रयुक्त शब्दावली सुसंगत नहीं है और इसलिए भ्रामक हो सकती है। यह अस्पष्टता, पर्यायवाची शब्दों के उपयोग और कार्यान्वयन का परिणाम है, जो मूल पैटर्न से परे जाकर अस्पष्ट हो सकता है।
 * 1) अनिश्चितता।
 * 2) टर्म कमांड अस्पष्ट है। उदाहरण के लिए, मूव अप, मूव अप एक एकल (मूव अप) कमांड को संदर्भित कर सकता है जिसे दो बार निष्पादित किया जाना चाहिए, या यह दो कमांड को संदर्भित कर सकता है, जिनमें से प्रत्येक एक ही कार्य  (ऊपर ले जाएं) करने के लिए होता है। यदि पूर्व कमांड को पूर्ववत स्टैक में दो बार जोड़ा जाता है, तो स्टैक पर दोनों आइटम एक ही कमांड इंस्टेंस को संदर्भित करते हैं। यह उचित हो सकता है जब एक आदेश सदैव उसी तरह पूर्ववत किया जा सकता है (उदाहरण के लिए नीचे जाएं)। गैंग ऑफ फोर (सॉफ्टवेयर) और #Java दोनों ही 'कमांड' शब्द की इस व्याख्या का उपयोग करते हैं। दूसरी ओर, यदि बाद वाले आदेशों को पूर्ववत स्टैक में जोड़ा जाता है, तो स्टैक दो अलग-अलग वस्तुओं को संदर्भित करता है। यह उचित हो सकता है जब स्टैक पर प्रत्येक ऑब्जेक्ट में ऐसी जानकारी होनी चाहिए जो आदेश को पूर्ववत करने की अनुमति देती है। उदाहरण के लिए, डिलीट सिलेक्शन कमांड को पूर्ववत करने के लिए, ऑब्जेक्ट में डिलीट किए गए टेक्स्ट की एक कॉपी हो सकती है ताकि इसे फिर से डाला जा सके, अगर डिलीट सिलेक्शन कमांड को पूर्ववत किया जाना चाहिए। ध्यान दें कि कमांड के प्रत्येक आह्वान के लिए एक अलग ऑब्जेक्ट का उपयोग करना भी जिम्मेदारी पैटर्न की श्रृंखला का एक उदाहरण है।
 * 3) शब्द निष्पादन भी संदिग्ध है। यह कमांड ऑब्जेक्ट के निष्पादित विधि द्वारा पहचाने गए कोड को चलाने का उल्लेख कर सकता है। हालाँकि, माइक्रोसॉफ्ट के विंडोज प्रेजेंटेशन फाउंडेशन में एक कमांड को निष्पादित माना जाता है जब कमांड की निष्पादित विधि लागू की गई है, लेकिन इसका मतलब यह नहीं है कि एप्लिकेशन कोड चला गया है। यह कुछ और घटना प्रसंस्करण के बाद ही होता है।
 * 4) पर्यायवाची और समानार्थी।
 * 5) क्लाइंट, स्रोत, आह्वानकर्ता: बटन, टूलबार बटन, या मेनू आइटम पर क्लिक किया गया, शॉर्टकट कुंजी उपयोगकर्ता द्वारा दबाया गया।
 * 6) कमांड ऑब्जेक्ट, रूटेड कमांड ऑब्जेक्ट, एक्शन ऑब्जेक्ट: एक सिंगलटन ऑब्जेक्ट (जैसे कि केवल एक कॉपीकमांड ऑब्जेक्ट है), जो कमांड से संबंधित शॉर्टकट कुंजियों, बटन छवियों, कमांड टेक्स्ट आदि के विषय  में जानता है। एक स्रोत/आह्वानकर्ता ऑब्जेक्ट कमांड/एक्शन ऑब्जेक्ट की निष्पादन/प्रदर्शन क्रिया विधि को कॉल करता है। कमांड/एक्शन ऑब्जेक्ट उचित स्रोत/आह्वानकर्ता ऑब्जेक्ट्स को सूचित करता है जब कमांड/एक्शन की उपलब्धता बदल जाती है। यह बटन और मेनू आइटम को निष्क्रिय होने की अनुमति देता है (ग्रे आउट) जब कोई कमांड/एक्शन निष्पादित/निष्पादित नहीं किया जा सकता है।
 * 7) प्राप्तकर्ता, टारगेट ऑब्जेक्ट: वह ऑब्जेक्ट जो कॉपी, पेस्ट, मूव आदि होने वाला है। प्राप्तकर्ता ऑब्जेक्ट उस विधि का मालिक होता है जिसे कमांड के एक्जीक्यूट विधि द्वारा कॉल किया जाता है। प्राप्तकर्ता आमतौर पर लक्ष्य ऑब्जेक्ट भी होता है। उदाहरण के लिए, यदि प्राप्तकर्ता ऑब्जेक्ट एक 'कर्सर' है और विधि को 'मूवअप' कहा जाता है, तो कोई उम्मीद करेगा कि कर्सर मूवअप एक्शन का लक्ष्य है। दूसरी ओर, यदि कोड को कमांड ऑब्जेक्ट द्वारा ही परिभाषित किया गया है, तो लक्ष्य ऑब्जेक्ट पूरी तरह से एक अलग ऑब्जेक्ट होगा।
 * 8) कमांड ऑब्जेक्ट, रूटेड इवेंट आर्ग्युमेंट्स, इवेंट ऑब्जेक्ट: वह ऑब्जेक्ट जो सोर्स से कमांड/एक्शन ऑब्जेक्ट तक, टार्गेट ऑब्जेक्ट से उस कोड तक जाता है जो कार्य  करता है। प्रत्येक बटन क्लिक या शॉर्टकट कुंजी का परिणाम एक नए कमांड/ईवेंट ऑब्जेक्ट में होता है। कुछ कार्यान्वयन कमांड/ईवेंट ऑब्जेक्ट में अधिक जानकारी जोड़ते हैं क्योंकि यह एक ऑब्जेक्ट (जैसे कॉपी कमांड) से दूसरे (जैसे दस्तावेज़ अनुभाग) में पारित किया जा रहा है। अन्य कार्यान्वयन कमांड/ईवेंट ऑब्जेक्ट्स को अन्य इवेंट ऑब्जेक्ट्स (जैसे बड़े बॉक्स के अंदर एक बॉक्स) में रखते हैं, क्योंकि वे नामकरण संघर्ष से बचने के लिए लाइन के साथ चलते हैं। (जिम्मेदारी पैटर्न की श्रृंखला भी देखें।)
 * 9) हैंडलर, ExecutedRoutedEventHandler, विधि, फंक्शन: वास्तविक कोड जो कॉपी, पेस्ट, मूविंग आदि करता है। कुछ कार्यान्वयन में हैंडलर कोड कमांड/एक्शन ऑब्जेक्ट का हिस्सा होता है। अन्य कार्यान्वयन में कोड प्राप्तकर्ता/लक्ष्य ऑब्जेक्ट का हिस्सा है, और अभी तक अन्य कार्यान्वयन में हैंडलरकोड को अन्य वस्तुओं से अलग रखा जाता है।
 * 10) कमांड मैनेजर, अनडू मैनेजर, शेड्यूलर, क्यू, डिस्पैचर, आह्वानकर्ता: एक ऑब्जेक्ट जो कमांड/इवेंट ऑब्जेक्ट्स को अनडू स्टैक या रीडू स्टैक पर रखता है, या जो कमांड/इवेंट ऑब्जेक्ट्स को तब तक होल्ड करता है जब तक अन्य ऑब्जेक्ट उन पर कार्य करने के लिए तैयार नहीं होते, या जो कमांड/इवेंट ऑब्जेक्ट को उपयुक्त प्राप्तकर्ता/टारगेट ऑब्जेक्ट या हैंडलर कोड पर रूट करता है।
 * 11) कार्यान्वयन जो मूल कमांड पैटर्न से काफी आगे जाते हैं।
 * 12) माइक्रोसॉफ्ट का विंडोज प्रेजेंटेशन फाउंडेशन (WPF), रूटेड कमांड पेश करता है, जो इवेंट प्रोसेसिंग के साथ कमांड पैटर्न को जोड़ता है। नतीजतन, कमांड ऑब्जेक्ट में अब लक्ष्य ऑब्जेक्ट का संदर्भ नहीं है और न ही एप्लिकेशन कोड का संदर्भ है। इसके बजाय, कमांड ऑब्जेक्ट के एक्जीक्यूट कमांड को लागू करने से एक तथाकथित एक्जिक्यूटेड रूटेड इवेंट होता है, जो कि इवेंट के टनलिंग या बबलिंग के दौरान एक तथाकथित बाइंडिंग ऑब्जेक्ट का सामना कर सकता है जो लक्ष्य की पहचान करता है और एप्लिकेशन कोड, जिसे उस बिंदु पर निष्पादित किया जाता है।

उदाहरण
एक साधारण स्विच पर विचार करें। इस उदाहरण में हम स्विच को दो आदेशों से कॉन्फ़िगर करते हैं: प्रकाश को चालू करने के लिए और प्रकाश को बंद करने के लिए।

कमांड पैटर्न के इस विशेष कार्यान्वयन का एक लाभ यह है कि स्विच का उपयोग किसी भी उपकरण के साथ किया जा सकता है, न कि केवल एक प्रकाश के साथ। निम्नलिखित सी # कार्यान्वयन में स्विच एक प्रकाश को चालू और बंद कर देता है, लेकिन स्विच का कन्स्ट्रक्टर अपने दो पैरामीटर के लिए कमांड के किसी उप-वर्ग को स्वीकार करने में सक्षम है। उदाहरण के लिए, आप इंजन शुरू करने के लिए स्विच को कॉन्फ़िगर कर सकते हैं।

यह भी देखें

 * बैच कतार
 * क्लोजर (कंप्यूटर विज्ञान)
 * कमांड कतार
 * फंक्शन ऑब्जेक्ट
 * जॉब शेड्यूलर
 * मॉडल-व्यू-कंट्रोलर
 * प्राथमिकता कतार
 * सॉफ्टवेयर डिजाइन पैटर्न
 * गैंग ऑफ फोर (सॉफ्टवेयर) | जीओएफ - डिजाइन पैटर्न

इतिहास
इंटरएक्टिव सिस्टम को लागू करने के लिए कमांड क्लास का उपयोग करने का पहला प्रकाशित उल्लेख हेनरी लिबरमैन द्वारा 1985 का एक लेख प्रतीत होता है। निष्पादन और पूर्ववत विधियों के साथ एक कमांड वर्ग का उपयोग करते हुए एक (बहु-स्तरीय) पूर्ववत-फिर से तंत्र का पहला प्रकाशित विवरण, और एक इतिहास सूची, बर्ट्रेंड मेयर की पुस्तक वस्तु-उन्मुख सॉफ्टवेयर निर्माण का पहला (1988) संस्करण प्रतीत होता है। खंड 12.2।

बाहरी संबंध

 * Command Pattern
 * Java Tip 68: Learn how to implement the Command pattern in Java