2009-04-14 6 views
60

मैं सिर्फ Chain of Responsibility पैटर्न पर पढ़ रहा हूं और मुझे एक परिदृश्य की कल्पना करने में परेशानी हो रही है जब मैं decorator पर इसका उपयोग करना पसंद करूंगा।मैं कभी सजावट पर जिम्मेदारी की श्रृंखला का उपयोग क्यों करूं?

आपको क्या लगता है? क्या सीओआर का कोई विशिष्ट उपयोग है?

+1

कृपया एक ऐसा कार्य जोड़ें जो आपको लगता है कि CoR के लिए कार्य है लेकिन आपने इसे सजावटी –

+0

के साथ हल किया है, निश्चित रूप से, मुझे ऑर्डर पूरा करने की आवश्यकता है और कुछ मामलों में मुझे बिल प्रिंट करना होगा। मेरा सजावटी समाधान एक ऑर्डर कॉम्प्लेशनप्रिंटडेकोरेटर में लिपटे कोर ऑर्डर कॉम्प्लेटर है जो सशर्त तर्क और प्रिंट लागू करता है। बस किसी भी श्रृंखला के साथ काम करता है। –

+0

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

उत्तर

53

तथ्य यह है कि आप किसी भी बिंदु पर श्रृंखला तोड़ सकते हैं सजावट पैटर्न से जिम्मेदारी पैटर्न की श्रृंखला को अलग करता है। अन्य सजावटकारों के साथ किसी भी बातचीत के बिना सजावटी को एक ही समय में निष्पादित करने के बारे में सोचा जा सकता है। एक श्रृंखला में लिंक को एक समय में निष्पादित करने के बारे में सोचा जा सकता है, क्योंकि वे प्रत्येक पिछले लिंक पर निर्भर करते हैं।

जब आप अपने कार्यक्रम को लिंक से बने चेन के रूप में अवधारणा बना सकते हैं, तो प्रत्येक लिंक या तो इसे संभाल सकता है या श्रृंखला को पास कर सकता है।

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

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

एक और स्थान कमांड पैटर्न का चेन गेम इंजनों में उपयोग किया जाता है। फिर, आप इंजन कार्यों, घटनाओं, और अन्य चीजों को हुक कर सकते हैं। गेम इंजन के मामले में, आप बस कार्यक्षमता जोड़ना नहीं चाहते हैं। आप कार्यक्षमता जोड़ना चाहते हैं और गेम इंजन को अपनी डिफ़ॉल्ट कार्रवाई करने से रोकना चाहते हैं।

+0

आईएमओ सीओआर पैटर्न में, हमारे पास कई (या सभी) हैंडलर (लिंक) ऑब्जेक्ट्स प्रत्येक अनुरोध के हैंडलिंग/प्रतिक्रिया के निर्माण में योगदान दे सकते हैं। – Rishi

+0

तो आप कह रहे हैं कि यह घोंसला के लिए एक प्रतिस्थापन हो सकता है अगर ... और कथन, सिवाय इसके कि अंत में कोई और खंड नहीं होगा? –

7

मैं कहूंगा कि उत्तरदायित्व की श्रृंखलासजावट का एक विशेष रूप है।

+0

एक पंक्ति सबकुछ बताती है – HakunaMatata

4

खैर मैं 2 स्थितियों के बारे में सोच सकते हैं:

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

अब और अधिक नहीं सोच सकता है, इस विषय में और अधिक सुनना अच्छा लगेगा।

13

चेन

से बचें और अधिक से अधिक एक वस्तु अनुरोध को पूरा करने का मौका देकर अपने रिसीवर के लिए एक अनुरोध के प्रेषक युग्मन। प्राप्त करने वाली वस्तुओं को चेन करें और चेन के साथ अनुरोध को तब तक पास करें जब तक कोई ऑब्जेक्ट इसे संभाल नहीं लेता।

बनाम

डेकोरेटर

एक वस्तु को गतिशील करने के लिए अतिरिक्त जिम्मेदारी देते हैं। सजावट कार्यक्षमता को विस्तारित करने के लिए उप-वर्गीकरण के लिए एक लचीला विकल्प प्रदान करता है।

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

+0

आप अलग-अलग क्रम में संलग्न कर सकते हैं, नहीं? –

+0

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

6

सजावट का उपयोग तब किया जाता है जब आप किसी ऑब्जेक्ट में कार्यक्षमता जोड़ना चाहते हैं।

सीओआर का उपयोग तब किया जाता है जब कई कलाकारों में से एक ऑब्जेक्ट पर कार्रवाई कर सकता है।

विशेष सजावटी को प्रकार के आधार पर एक कार्रवाई करने के लिए बुलाया जाता है; जबकि सीओआर एक परिभाषित श्रृंखला के साथ ऑब्जेक्ट पास करता है जब तक कि एक अभिनेता निर्णय लेता है कि कार्रवाई पूरी हो गई है।

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

+0

ठीक है, लेकिन मेरा मुद्दा यह है कि आप एक सजावटी का उपयोग उतना ही कम कर सकते हैं जितना कम प्रयास नहीं। तो बिल्ली में भी सीओआर क्यों शामिल है? –

+3

लेकिन एक सजावट एक अलग पैटर्न है - सीओआर के साथ, वस्तु अभिनेता से अभिनेता तक जाती है जब तक कि कोई कहता है कि यह कार्रवाई पूरी नहीं हुई है; सजावटी के साथ, एक विशेष वर्ग के कार्यान्वयन पर कार्रवाई की जा रही है। – Ragoczy

14

इन पैटर्न के बीच का अंतर यह नहीं है कि श्रृंखला कब टूटी जा सकती है (जो एक श्रृंखला मानती है) या जब अतिरिक्त व्यवहार निष्पादित किया जाता है। वे इस बात से संबंधित हैं कि वे दोनों अधिक लचीला समाधान प्रदान करने के लिए विरासत के पक्ष में संरचना का उपयोग करते हैं।

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

सीओआर पैटर्न मौजूदा व्यवहार को संशोधित कर सकता है जो विरासत का उपयोग कर मौजूदा विधि को ओवरराइड करने जैसा है। आप "चेन" जारी रखने या संदेश को स्वयं संभालने के लिए super.xxx() को कॉल करना चुन सकते हैं।

तो अंतर सूक्ष्म है, लेकिन एक डेकोरेटर का एक उदाहरण की मदद करनी चाहिए:

interface Animal 
{ 
    Poo eat(Food food); 
} 

class WalkingAnimal implements Animal 
{ 
    Animal wrapped; 
    WalkingAnimal(Animal wrapped) 
    { 
     this.wrapped = wrapped; 
    } 

    Position walk(Human walker) 
    { 
    }; 

    Poo eat(Food food) 
    { 
     return wrapped.eat(food); 
    } 
} 

class BarkingAnimal implements Animal 
{ 
    Animal wrapped; 
    BarkingAnimal(Animal wrapped) 
    { 
     this.wrapped = wrapped; 
    } 

    Noise bark() 
    { 
    }; 

    Poo eat(Food food) 
    { 
     bark(); 
     return wrapped.eat(); 
    } 
} 

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

सभी बार्किंगएनिमल भी खाने से पहले एक बार छाल जो मौजूदा कार्यक्षमता को बदल चुका है और इसी तरह सीओआर के समान है। लेकिन इरादा सीओआर जैसा नहीं है, जो कि कई लोगों के एक पशु को खोजने के लिए भोजन खाएगा। यहां व्यवहार का उद्देश्य व्यवहार को संशोधित करना है।

आप कल्पना कर सकते हैं कि एक मानव को खोजने के लिए एक सीओआर लागू किया जा रहा है जो जानवर को चलने के लिए ले जाएगा। इसे उपरोक्त chained या एक स्पष्ट सूची के रूप में या किसी भी लिंक्ड सूची के रूप में कार्यान्वित किया जा सकता है।

आशा है कि यह उचित रूप से स्पष्ट है!

जॉन

+1

यह वह जवाब है जिसने मुझे अंततः महसूस किया कि जिस तरह से मुझे लगता है कि ये पैटर्न गलत थे! मैं किताब में प्रस्तुत कक्षा आरेखों के संदर्भ में संरचनात्मक रूप से सोच रहा था, उत्तरदायी के साथ एक अमूर्त अभिभावक वर्ग के साथ उत्तरदायित्व की श्रृंखला के साथ। लेकिन गोफ ने नोट किया है कि आप इसे मिश्रित विरासत के साथ भी कर सकते हैं, जिस स्थिति में कक्षा आरेख समान दिखते हैं। लेकिन इरादे और व्यवहार अंतर का मुख्य तत्व, विशेष रूप से DECORATOR इंटरफ़ेस को कैसे बढ़ाता है, महत्वपूर्ण है। बहुत बढ़िया जवाब। –

1

मैं मानता हूँ कि संरचनात्मक दृष्टि से यह दो पैटर्न बहुत समान हैं। मेरा विचार अंतिम व्यवहार के बारे में है:

सीओआर तत्व की क्लासिक व्याख्या में जो अनुरोध को संभालता है, श्रृंखला को तोड़ देता है।

यदि सजावट में कोई तत्व श्रृंखला को तोड़ता है तो यह गलत सजावट के कार्यान्वयन के कारण होगा, क्योंकि व्यवहार का आधार हिस्सा खो जाएगा। और सजावट का विचार नए व्यवहार के पारदर्शी जोड़ है जब आधार व्यवहार छूटा रहता है।

0

मुझे लगता है कि इन दो पैटर्न को लागू करने के लिए स्थितियां अलग-अलग हैं। और वैसे, सजावटी पैटर्न के लिए, सजावटी को उस घटक को जानना चाहिए जो इसे लपेटा गया है। और सीओआर के लिए, विभिन्न इंटरसेप्टर एक-दूसरे के बारे में कुछ भी नहीं जानते थे।

+0

सजावटी को केवल इंटरफ़ेस को जानने की आवश्यकता है, कोई कार्यान्वयन नहीं। – dave1010

1
  1. कीवर्ड 'विस्तार' - स्थैतिक विस्तार।
  2. सजावटी पैटर्न - गतिशील विस्तार।
  3. उत्तरदायित्व पैटर्न की श्रृंखला - के साथ एक कमांड ऑब्जेक्ट की प्रोसेसिंग ऑब्जेक्ट्स का एक सेट और उन ऑब्जेक्ट्स एक दूसरे को नहीं जानते हैं।
0

चार परिभाषाओं की गिरोह पढ़ने के बाद, मुझे विश्वास नहीं है कि एक वास्तविक अंतर है। (सुविधा के लिए शामिल)

  • डेकोरेटर: आदेश में अपने मौजूदा जिम्मेदारियों को संशोधित करने के वस्तुओं के गतिशील रैपिंग के लिए अनुमति देता है और व्यवहार
  • जिम्मेदारी की चेन: एक से अधिक वस्तु प्राप्त जोड़ने के द्वारा एक अनुरोध को पूरा करने का अवसर देता है एक साथ वस्तुओं

विकिपीडिया उन्हें थोड़ा बाहर निकाल देता है, लेकिन इसमें से कुछ तरह मनमाना है।

  • सजावटी आमतौर पर एक लिंक्ड सूची के रूप में लागू किया जाता है। लेकिन मुझे लगता है कि पैटर्न के "भाग" के रूप में माना जाने वाला बहुत कम स्तर है।
  • उत्तरदायित्व लिंक की श्रृंखला केवल तभी डेटा संभालती है जब यह उनकी ज़िम्मेदारी है; लेकिन जिम्मेदारी निर्धारित करना और डेटा हैंडलिंग व्यवहार का दोनों हिस्सा हैं। सजावटी इसे आसानी से कर सकते हैं।
  • सजावटी के लिए आपको प्रतिनिधि को कॉल करने की आवश्यकता है।
  • एक "शुद्ध" सीओआर लिंक केवल प्रतिनिधि को कॉल करना चाहिए यदि यह डेटा को संभाल नहीं लेता है।

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

वास्तव में इन विशेषताओं को लागू करने के लिए, आपको निम्न की तरह कुछ चाहिए।

से लागू डेकोरेटर:

abstract class Decorated { 

public Decorated delegate; 

public final Object doIt(Object args) { 
    Object returnVal = behavior(arg); 
    if(delegate != null) returnVal = delegate.doit(returnVal); 
    return returnVal; 
} 

protected abstract Object behavior(Object args); //base or subclass behavior 
} 

उत्तरदायित्व का बलपूर्वक चेन:

abstract class Link { 

public Link delegate; 

public final Object processIt(Obect args) { 
    Object returnVal = args; 
    if(isMyResponsibility) returnVal = processingBehavior(returnVal); 
    else returnVal = delegate.processIt(returnVal); 
    return returnVal; 
} 

protected abstract Boolean isMyResponsibility(Object args); 

protected abstract Object processingBehavior(Object args); 
} 

(वैकल्पिक रूप से, तुम सिर्फ एक लाइन जावाडोक लिए, अगर सब आप चाहते हैं responsibiity की अपने आप को दोषमुक्त करने के लिए है जोड़ सकता है अगर कोई और आपके डिजाइन को खराब कर देता है - लेकिन इसे मौका क्यों छोड़ दें?)

2

सजावटी

  1. Decorator पैटर्न व्यवहार गतिशील रूप से एक व्यक्ति वस्तु के लिए जोड़ा जा करने के लिए अनुमति देता है।

  2. यह कार्यक्षमता बढ़ाने के लिए उप वर्गीकरण के लिए एक लचीला विकल्प प्रदान करता है। हालांकि यह विरासत का उपयोग करता है, यह सबसे कम आम denominator (एलसीडी) इंटरफ़ेस से प्राप्त होता है। डेकोरेटर

    के लिए UML diagram for Decorator

    परिणाम

यूएमएल आरेख:

  1. सजावट के साथ यह भी गतिशील रूप से जोड़ा कार्यक्षमताओं दूर करने के लिए संभव है।
  2. सजावट रनटाइम पर ऑब्जेक्ट्स को कार्यक्षमता जोड़ती है जो डीबगिंग सिस्टम कार्यक्षमता को कठिन बना देती है।

उपयोगी लिंक्स:

When to Use the Decorator Pattern?

विकिपीडिया

decorator से Decorator_pattern sourcemaking जिम्मेदारी के

चेन से:

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

यूएमएल आरेख

enter image description here

यह पैटर्न जब अधिक प्रभावी है:

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

उपयोगी लिंक्स:

विकिपीडिया से Chain-of-responsibility_pattern

chain-of-responsibility-pattern oodesign

chain_of_responsibility से sourcemaking

रियल दुनिया उदाहरण से: एक कंपनी, एक नामित भूमिका में खरीद अनुरोध पर कार्रवाई करने के लिए विशेष सीमा होती है। यदि नामित भूमिका वाले व्यक्ति के पास खरीद बिल को मंजूरी देने के लिए पर्याप्त शक्ति नहीं है, तो वह अपने उत्तराधिकारी को आदेश/अनुरोध अग्रेषित करेगा, जिसके पास अधिक शक्ति है। कमांड संसाधित होने तक यह श्रृंखला जारी रहेगी।

संबंधित मुद्दे