एक रणनीति पैटर्न और एक कमांड पैटर्न का उपयोग करना


121

दोनों डिजाइन पैटर्न एक एल्गोरिथ्म को एन्क्रिप्ट करते हैं और उनके कॉलिंग वर्गों से कार्यान्वयन विवरणों को डिक्रिप्ट करते हैं। एकमात्र अंतर जो मैं समझ सकता हूं कि रणनीति पैटर्न निष्पादन के लिए मापदंडों में लेता है, जबकि कमांड पैटर्न नहीं करता है।

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

क्या दिशा-निर्देश निर्धारित करते हैं कि एक पैटर्न या दूसरे का उपयोग करना है या नहीं?

जवाबों:


94

मैं इन दो पैटर्नों के बीच के अंतरों को समझाने में मदद करने के लिए कई GoF डिज़ाइन पैटर्न की एक एनकैप्सुलेशन पदानुक्रम तालिका शामिल कर रहा हूँ। उम्मीद है कि यह बेहतर दिखाता है कि प्रत्येक व्यक्ति क्या करता है इसलिए मेरी व्याख्या अधिक समझ में आती है।

सबसे पहले, पदानुक्रम उस स्कोप को सूचीबद्ध करता है जिसके लिए एक दिया गया पैटर्न लागू होता है, या किसी स्तर के विवरण को एनकैप्सुलेट करने के लिए उपयोग करने के लिए उपयुक्त पैटर्न, जिस तालिका के आधार पर आप शुरू करते हैं।

डिजाइन पैटर्न इनकैप्सुलेशन पदानुक्रम तालिका

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

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

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


इसलिए अगर मेरे पास एक ऐसी प्रणाली है जो एक "फ़िल्टर पाइपलाइन" के साथ परिणाम फ़िल्टर करती है और प्रतिनिधियों को फ़िल्टर के रूप में उपयोग करती है (जहां एक फ़ंक्शन के भीतर फ़िल्टर के प्रत्येक एल्गोरिदम को एन्क्रिप्ट किया जाएगा) क्या इसे कमांड पैटर्न माना जाएगा? इस मामले में मैं फ़िल्टर फ़ंक्शन के लिए प्रतिनिधि को इनपुट और आउटपुट के संदर्भ में प्रत्येक फ़िल्टर का पालन करने के लिए एक प्रकार का अनुबंध प्रदान करता हूं।
केटीएफ

4
@ टीटीएफ, नहीं। कमांड पैटर्न एक ऑब्जेक्ट को नियोजित करता है जिसमें किसी वस्तु की विधि को लागू करने के लिए आवश्यक जानकारी (जैसे, सभी नहीं), जैसे, रिसीवर, चयनकर्ता, तर्क) होते हैं। यह एक सरलीकृत पैटर्न है जिसे अन्य डिज़ाइन पैटर्न जैसे कि चेन ऑफ़ रिस्पॉन्सिबिलिटी, कलेक्शन और आपके द्वारा वर्णित पाइपलाइन पैटर्न में उपयोग किया जा सकता है। आपके प्रतिनिधियों द्वारा प्रदान किया गया "अनुबंध का प्रकार" एक और पैटर्न, इंटरफ़ेस है।
हपरनिकेतेस

50

रणनीतियाँ एल्गोरिदम को कूटबद्ध करती हैं। अनुरोध के रिसीवर से प्रेषक को अलग करता है, वे एक अनुरोध को एक वस्तु में बदल देते हैं।

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


यह समझ में आता है कि en.wikipedia.org/wiki/Command_Pattern क्लाइंट और इनवॉकर बंधे हैं, लेकिन एक ही समय में, वे एक दूसरे के बारे में नहीं जानते हैं!
कल्पेश सोनी

26

बहुत पुराने प्रश्न का उत्तर दे रहा हूं। (क्या कोई सबसे अधिक मतदान के बजाय नवीनतम उत्तर देख रहा है?)

यह समानता के कारण होने के लिए एक वैध भ्रम है। रणनीति और कमांड पैटर्न दोनों ही इनकैप्सुलेशन का उपयोग करते हैं । लेकिन यह उन्हें समान नहीं बनाता है।

महत्वपूर्ण अंतर यह है कि क्या समझाया गया है। OO सिद्धांत, दोनों पैटर्न निर्भर करते हैं, जो अलग-अलग होते हैं

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

आदेश के मामले में, जो भिन्न होता है वह स्वयं अनुरोध है। अनुरोध से आ सकती है File Menu > Deleteया Right Click > Context Menu > Deleteया Just Delete Button pressed। सभी तीन मामले एक ही प्रकार के 3 कमांड ऑब्जेक्ट उत्पन्न कर सकते हैं। ये आदेश ऑब्जेक्ट केवल हटाने के लिए 3 अनुरोधों का प्रतिनिधित्व करते हैं; विलोपन एल्गोरिथ्म नहीं। चूंकि अनुरोध अब वस्तुओं का गुच्छा हैं, इसलिए हम उन्हें आसानी से प्रबंधित कर सकते हैं। अचानक इसे पूर्ववत या फिर से करना जैसी कार्यक्षमता प्रदान करने के लिए तुच्छ हो जाता है।

इससे कोई फर्क नहीं पड़ता कि कमांड अनुरोधित तर्क को कैसे लागू करता है। कॉलिंग एग्जीक्यूट () पर, यह विलोपन को ट्रिगर करने के लिए एक एल्गोरिथ्म को लागू कर सकता है या इसे अन्य वस्तुओं को भी सौंप सकता है, किसी रणनीति को भी सौंप सकता है। यह केवल कमांड पैटर्न का कार्यान्वयन विवरण है। यही कारण है कि इसे आदेश के रूप में नामित किया गया है, हालांकि यह अनुरोध करने के लिए एक विनम्र तरीका नहीं है : -)

रणनीति के साथ इसका विरोध करें; यह पैटर्न केवल वास्तविक तर्क से संबंधित है जिसे निष्पादित किया जाता है। यदि हम ऐसा करते हैं, तो यह कक्षाओं के न्यूनतम सेट के साथ व्यवहार के विभिन्न संयोजनों को प्राप्त करने में मदद करता है, इस प्रकार वर्ग विस्फोट को रोकता है।

मुझे लगता है, कमांड हमें एनकैप्सुलेशन की हमारी समझ को व्यापक बनाने में मदद करता है जबकि रणनीति एनकैप्सुलेशन और पॉलीमॉर्फिज़्म का प्राकृतिक उपयोग प्रदान करती है।


15

जिस तरह से मैं इसे देखता हूं वह यह है कि आपके पास एक ही काम करने के कई तरीके हैं, उनमें से प्रत्येक एक रणनीति है, और रनटाइम पर कुछ निर्धारित करता है कि कौन सी रणनीति निष्पादित होती है।

शायद पहले StrategyOne की कोशिश करो, अगर परिणाम पर्याप्त अच्छे नहीं हैं, तो StrategyTwo की कोशिश करें ...

कमांड अलग-अलग चीजों के लिए बाध्य हैं, जिन्हें TryToWalkAcrossTheRoomCommand की तरह होना चाहिए। जब भी किसी वस्तु को कमरे के पार चलने की कोशिश करनी चाहिए, तो यह आदेश निकाल दिया जाएगा, लेकिन इसके अंदर, यह कमरे में चलने की कोशिश करने के लिए StrategyOne और StrategyTwo की कोशिश कर सकता है।

निशान


2
पुन: "एक ही काम करने के कई तरीके" - यह रणनीति के कुछ सामान्य उदाहरणों के साथ संघर्ष लगता है। विशेष रूप से वे हैं जहां कार्यान्वयन कक्षाएं हैं जो जोड़, घटाव, गुणा, आदि करते हैं। शायद वे अच्छे उदाहरण नहीं हैं?
जोशुआ डेविस

1
@JoshuaDavis ये सभी "सबस्टैटेगीज" एक रणनीति के विशेष मामले हैं: अंकगणितीय संचालन । उनके पास सामान्य तर्क (2 ऑपरेंड) होते हैं और परिणाम के रूप में एक मूल्य पैदा करते हैं। बहुत कुछ ऐसा ही किया जा रहा है (ब्लैकबॉक्स होने के नाते) कार्यान्वयन के आधार पर, अपने अलग तरीके से बात करते हैं। इसलिए मैं यहाँ कोई संघर्ष नहीं देख रहा हूँ, लेकिन, इसके विपरीत: अच्छा उदाहरण =)
जंगल_मूल

7

मेरी राय में गलत हो सकता है, लेकिन मैं कमांड को फंक्शन-टू-एग्जीक्यूट या रिएक्शन के रूप में मानता हूं । कम से कम दो खिलाड़ी होने चाहिए: वह जो कार्रवाई का अनुरोध करता है, और वह जो कार्रवाई को अंजाम देता है। GUI कमांड पैटर्न के लिए विशिष्ट उदाहरण है:

  • एप्लिकेशन टूलबार के सभी बटन किसी न किसी कार्रवाई से जुड़े हैं।
  • बटन इस मामले में निष्पादक है।
  • इस मामले में कार्रवाई कमान है।

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

रणनीति थोड़ी अलग है: यह अधिक कुछ क्षेत्र के लिए बाध्य है। रणनीति एक तिथि को प्रारूपित करने के लिए एक नियम को परिभाषित कर सकती है (UTC में? स्थानीय विशिष्ट?) ("तिथि सूत्री" रणनीति) या ज्यामितीय आकृति के लिए वर्ग की गणना करने के लिए ("वर्ग कैलकुलेटर" रणनीति)। रणनीतियाँ इस अर्थ में फ्लाईवेट ऑब्जेक्ट हैं, जो इनपुट ("तिथि", "आंकड़ा", ...) के रूप में कुछ लेते हैं और इसके आधार पर कुछ निर्णय लेते हैं। शायद सबसे अच्छा नहीं, लेकिन रणनीति का अच्छा उदाहरण javax.xml.transform.Sourceइंटरफ़ेस के साथ जुड़ा हुआ है: इस पर निर्भर करता है कि पारित वस्तु है DOMSourceया SAXSourceया StreamSourceरणनीति (= XSLT ट्रांसफार्मर इस मामले में) इसे संसाधित करने के लिए विभिन्न नियम लागू होंगे। कार्यान्वयन एक सरल switchया शामिल हो सकता है जिम्मेदारी पैटर्न की श्रृंखला

लेकिन वास्तव में इन दोनों पैटर्नों के बीच कुछ सामान्य है: कमांड और रणनीतियाँ एल्गोरिदम को एक ही अर्थ क्षेत्र के भीतर घेरती हैं।


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

मैं सहमत हूं, हालांकि जैसा कि जिम ने कहा कि मैं कॉलबैक के संदर्भ को हटाने के लिए संपादित करूंगा।
JARC

धन्यवाद, मैंने कुछ एक्सटेंशन किए हैं। अगर आप सहमत / असहमत हैं तो मुझे बताएं।
dma_k

5

कमान:

मौलिक संघटक:

  1. कमांड अमूर्त आदेशों के लिए एक इंटरफ़ेस घोषित करता है जैसेexecute()
  2. रिसीवर जानता है कि किसी विशेष कमांड को कैसे निष्पादित किया जाए
  3. Invoker रखती ConcreteCommand , जो निष्पादित किया जाना है
  4. ग्राहक बनाता है ConcreteCommand और असाइन रिसीवर
  5. कंक्रीटकमांड कमान और रिसीवर के बीच बाध्यकारी को परिभाषित करता है

कार्यप्रवाह:

ग्राहक कॉल Invoker => Invoker कॉल ConcreteCommand => ConcreteCommand कॉल रिसीवर विधि है, जो लागू सार कमान विधि।

लाभ : क्लाइंट कमांड और रिसीवर में परिवर्तन पर प्रभाव नहीं डालता है। Invoker क्लाइंट और रिसीवर के बीच ढीली युग्मन प्रदान करता है। आप एक ही Invoker के साथ कई कमांड चला सकते हैं।

कमांड पैटर्न आपको एकही Invoker का उपयोग करकेविभिन्न रिसीवर पर एक कमांड निष्पादित करने की अनुमति देता है। आक्रमणकारी रिसीवर के प्रकार से अनजान है

अवधारणाओं की बेहतर समझ के लिए, यह JournalDev पर एक नजर है लेख से पंकज कुमार और dzone लेख द्वारा जेम्स Sugrue विकिपीडिया लिंक के अलावा।

आप कमांड पैटर्न का उपयोग कर सकते हैं

  1. चालान और कमांड के रिसीवर को घटाएं

  2. कॉलबैक तंत्र को लागू करें

  3. पूर्ववत और फिर से कार्यक्षमता को लागू करें

  4. आदेशों का इतिहास बनाए रखें

java.lang.Threadकमांड पैटर्न का एक अच्छा कार्यान्वयन है । आप का इलाज कर सकते थ्रेड invoker और वर्ग को लागू करने के रूप में Runnable रूप ConcreteCommonad / रिसीवर और run()के रूप में विधि कमान

आदेश पैटर्न के पूर्ववत करें / फिर से संस्करण को थियोडोर नॉरवेल के लेख में पढ़ा जा सकता है

रणनीति:

रणनीति पैटर्न समझने में बहुत सरल है। जब इस पैटर्न का उपयोग करें

एल्गोरिथ्म के लिए आपके पास कई कार्यान्वयन हैं और एल्गोरिथ्म का कार्यान्वयन विशेष परिस्थितियों के आधार पर रन टाइम में बदल सकता है

एयरलाइन बुकिंग सिस्टम के किराया घटक का एक उदाहरण लें

एयरलाइंस अलग-अलग समय अवधि - पीक और ऑफ पीक महीनों के दौरान अलग-अलग किराये की पेशकश करना चाहेंगे। ऑफ पीक यात्रा के दिनों के दौरान, यह आकर्षक छूट प्रदान करके मांग को प्रोत्साहित करना चाहता है।

रणनीति पैटर्न के मुख्य takeaways :

  1. यह एक व्यवहारिक पैटर्न है
  2. यह प्रतिनिधिमंडल पर आधारित है
  3. यह विधि व्यवहार को संशोधित करके ऑब्जेक्ट के हिम्मत को बदलता है
  4. इसका उपयोग एल्गोरिदम के परिवार के बीच स्विच करने के लिए किया जाता है
  5. यह रन टाइम में ऑब्जेक्ट के व्यवहार को बदल देता है

कोड उदाहरण के साथ संबंधित पोस्ट:

कमांड डिजाइन पैटर्न का उपयोग करना

रणनीति पैटर्न का वास्तविक विश्व उदाहरण


0

मेरे लिए, अंतर एक इरादे का है। दोनों पैटर्न के कार्यान्वयन बहुत समान हैं, लेकिन अलग-अलग उद्देश्य हैं:

  • एक रणनीति के लिए, ऑब्जेक्ट का उपयोग करने वाला घटक जानता है कि ऑब्जेक्ट क्या करता है (और इसका उपयोग अपने काम का एक हिस्सा करने के लिए करेगा), लेकिन यह परवाह नहीं करता है कि यह कैसे करता है।

  • एक कमांड के लिए, ऑब्जेक्ट का उपयोग करने वाला घटक न तो जानता है कि कमांड क्या करता है और न ही यह कैसे करता है - यह सिर्फ यह जानता है कि इसे कैसे लागू करना है। कॉल करने वाले का कार्य केवल कमांड चलाना है - कमांड द्वारा किया गया प्रोसेसिंग कॉलर के मुख्य कार्य का हिस्सा नहीं बनता है।

यह अंतर है - क्या घटक का उपयोग करने वाली वस्तु वास्तव में घटक के बारे में जानता है या परवाह करता है? अधिकांश समय यह इस आधार पर निर्धारित किया जा सकता है कि क्या पैटर्न ऑब्जेक्ट अपने आह्वान पर एक मूल्य लौटाता है। यदि इनवॉकर इस बात की परवाह करता है कि पैटर्न ऑब्जेक्ट क्या करता है, तो वह शायद कुछ वापस करना चाहेगा और यह एक रणनीति होगी। यदि यह किसी भी रिटर्न वैल्यू के बारे में परवाह नहीं करता है, तो यह संभवतः एक कमांड है (ध्यान दें, जावा कॉलेबल जैसा कुछ अभी भी एक कमांड है, क्योंकि यह एक वैल्यू लौटाता है, कॉल करने वाले को वैल्यू की परवाह नहीं है - यह बस इसे वापस पास करता है। जो कुछ भी मूल रूप से कमांड की आपूर्ति करता है)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.