कमांड पैटर्न

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

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

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

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

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

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

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

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


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

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

नीचे यूएमएल कक्षा और अनुक्रम आरेख भी देखें।

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

एकीकृत मॉडलिंग भाषा अनुक्रम आरेख क्रम परस्पर क्रिया दिखाता है:   ऑब्जेक्ट     ऑब्जेक्ट कॉल    है।  एक    ऑब्जेक्ट पर    कॉल करता है, जो अनुरोध करता है।

उपयोग

 * जीयूआई बटन और मेनू आइटम: स्विंग (जावा) और बोरलैंड डेल्फी प्रोग्रामिंग में, एक कमांड ऑब्जेक्ट है। वांछित कमांड को निष्पादित करने की क्षमता के अतिरिक्त, एक Action में संबद्ध चिह्न, कुँजीपटल शॉर्टकट, टूलटिप टेक्स्ट, इत्यादि हो सकते हैं। टूलबार बटन या मेनू आइटम घटक को मात्र  Action ऑब्जेक्ट का उपयोग करके पूर्ण रूप से प्रारंभ किया जा सकता है।
 * मैक्रो (कंप्यूटर विज्ञान) रिकॉर्डिंग: यदि सभी उपयोगकर्ता क्रियाएं कमांड ऑब्जेक्ट् द्वारा दर्शाई जाती हैं, तो एक प्रोग्राम मात्र कमांड ऑब्जेक्ट्स की सूची को क्रियान्वित करते हुए क्रियाओं के अनुक्रम को रिकॉर्ड कर सकता है। यह फिर उसी कमांड ऑब्जेक्ट को क्रम में फिर से निष्पादित करके उसी क्रिया को वापस चला सकता है। यदि प्रोग्राम एक स्क्रिप्टिंग इंजन को  अंतःस्थापित करता है, तो प्रत्येक कमांड ऑब्जेक्ट  toScript विधि एक को लागू कर सकता है, और फिर उपयोगकर्ता क्रियाओं को स्क्रिप्ट के रूप में सरलता से रिकॉर्ड किया जा सकता है।
 * कोड गतिशीलता: जावा जैसी भाषाओं का उपयोग करना जहां कोड को एक स्थान से दूसरे स्थान पर यूआरएलक्लासलोडर और कोडबेस के माध्यम से प्रवाहित/स्लिप किया जा सकता है, कमांड नए व्यवहार को दूरस्थ स्थानों (ईजेबी कमांड, मास्टर वर्कर) तक पहुंचाने में सक्षम बना सकते हैं।
 * मल्टी-लेवल अनडू : यदि किसी प्रोग्राम में सभी उपयोगकर्ता क्रियाएं कमांड ऑब्जेक्ट के रूप में लागू की जाती हैं, तो प्रोग्राम वर्तमान में निष्पादित कमांड का स्टैक रख सकता है। जब उपयोगकर्ता कमांड को पूर्ववत करना चाहता है, तो प्रोग्राम मात्र वर्तमान कमांड ऑब्जेक्ट को पॉप करता है और 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