प्रॉक्सी, डेकोरेटर, एडेप्टर और ब्रिज पैटर्न कैसे भिन्न होते हैं?


403

मैं प्रॉक्सी पैटर्न देख रहा था, और मेरे लिए यह सज्जाकार, एडेप्टर और ब्रिज पैटर्न की तरह एक बहुत अच्छा लग रहा है। क्या मैं कुछ गलत समझ रहा हूँ? क्या फर्क पड़ता है? मैं दूसरों के बनाम प्रॉक्सी पैटर्न का उपयोग क्यों करूंगा? आपने वास्तविक विश्व परियोजनाओं में अतीत में उनका उपयोग कैसे किया है?


4
अक्सर ऐसे पैटर्न होते हैं जो बहुत समान दिखते हैं, लेकिन उनके इरादे में भिन्नता होती है (रणनीति और राज्य पैटर्न दिमाग में आते हैं)। मुझे लगता है कि यह अक्सर इस तथ्य के कारण है कि डिजाइन पैटर्न सामान्य ठोस डिजाइन सिद्धांतों पर आधारित हैं।
जेसन डाउन

5
ठीक है, इन चार पैटर्न में ठीक उसी कार्यान्वयन विवरण हैं। राज्य छंद की रणनीति को कम से कम राज्य-पूर्ण छंदों को स्टेटलेस (अधिकांश भाग के लिए) के रूप में अभिव्यक्त किया जा सकता है। अक्सर, रणनीति सिर्फ विधि इंजेक्शन होती है, जहां राज्य पैटर्न अधिक कॉल करने के लिए इंटरफ़ेस का उपयोग करता है और एक विधि कॉल को दूर करता है। रणनीति, भी, दिन के अंत में, OO दुनिया में कार्यात्मक प्रोग्रामिंग की अनुमति देने के लिए एक हैक है।
चार्ल्स ग्राहम

जवाबों:


648

प्रॉक्सी, डेकोरेटर, एडेप्टर, और ब्रिज एक वर्ग को "लपेटने" पर सभी विविधताएं हैं। लेकिन उनके उपयोग अलग हैं।

  • प्रॉक्सी का उपयोग तब किया जा सकता है जब आप किसी ऑब्जेक्ट को आलसी-इंस्टेंट करना चाहते हैं, या इस तथ्य को छिपाना चाहते हैं कि आप दूरस्थ सेवा को कॉल कर रहे हैं, या ऑब्जेक्ट तक पहुंच को नियंत्रित करते हैं।

  • डेकोरेटर को "स्मार्ट प्रॉक्सी" भी कहा जाता है। इसका उपयोग तब किया जाता है जब आप किसी ऑब्जेक्ट में कार्यक्षमता जोड़ना चाहते हैं, लेकिन उस ऑब्जेक्ट के प्रकार का विस्तार करके नहीं। यह आपको रनटाइम पर ऐसा करने की अनुमति देता है।

  • एडेप्टर का उपयोग तब किया जाता है जब आपके पास एक सार इंटरफ़ेस होता है, और आप उस इंटरफ़ेस को किसी अन्य ऑब्जेक्ट पर मैप करना चाहते हैं जिसमें समान कार्यात्मक भूमिका होती है, लेकिन एक अलग इंटरफ़ेस।

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

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


7
अच्छा उत्तर। आप जंगल में इसे देखने के कुछ उदाहरण जोड़ने के लायक हो सकते हैं? उदाहरण के लिए वेब सेवाओं में प्रॉक्सी कक्षाएं। मुझ से +1।
कूपर में रोब कूपर

5
@ रोब: धन्यवाद, लेकिन मैं इस जवाब को छोटा और मीठा रखना चाहूंगा। मैं आपको जंगली में उदाहरणों के साथ एक और उत्तर लिखने के लिए प्रोत्साहित करता हूं!
बिल करविन 19

8
@RobertDailey डेकोरेटर नियंत्रण प्रकार के पदानुक्रमों से बचने के लिए भी अच्छा है। उदाहरण के लिए , मान लें कि आपके पास GUI में एक विंडो है और आप वैकल्पिक स्क्रॉल बार रखना चाहते हैं। आपके पास Window, VScrollWindow, HScrollWindow और VHScrollWindow कक्षाएं हो सकती हैं या आप विंडो पर VScroll और HScroll सज्जाकार बना सकते हैं।
इवा

1
@RobertDailey, डेकोरेटर है रचना।
बिल कार्विन

1
और क्या होगा यदि आप लिपटे ऑब्जेक्ट 1: 1 के इंटरफ़ेस को डुप्लिकेट करना चाहते हैं, लेकिन फिर कुछ अतिरिक्त तरीके जोड़ते हैं? यह एक डेकोरेटर या एक एडेप्टर है?
दान

198

जैसा कि बिल का जवाब कहता है, उनके उपयोग के मामले अलग हैं

तो उनकी संरचनाएं हैं।

  • प्रॉक्सी और डेकोरेटर दोनों के लिपटे प्रकार के समान इंटरफ़ेस हैं, लेकिन प्रॉक्सी हुड के नीचे एक उदाहरण बनाता है, जबकि डेकोरेटर कंस्ट्रक्टर में एक उदाहरण लेता है।

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

  • ब्रिज और एडॉप्टर दोनों एक मौजूदा प्रकार पर इंगित करते हैं। लेकिन पुल एक अमूर्त प्रकार पर इंगित करेगा, और एडाप्टर एक ठोस प्रकार को इंगित कर सकता है। पुल आपको रनटाइम पर कार्यान्वयन को युग्मित करने की अनुमति देगा, जबकि एडाप्टर आमतौर पर नहीं होगा।


30
आपका उत्तर बिल के पैटर्न के 5 अध्यायों को बहुत अच्छे से लपेटता है। कोई उन्हें पुस्तक का उच्च-स्तरीय (सरल: पढ़ा हुआ) इंटरफ़ेस कह सकता है।
जोनास आयशर

54

मेरा विषय पर ले।

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

ढीले कपलिंग को बढ़ावा देने से वे अपरिहार्य परिवर्तनों के साथ एक बार स्थिर कोड को कम कर देते हैं और साथी डेवलपर्स के लिए बेहतर पठनीय बन जाते हैं।

अनुकूलक

एडॉप्टर एक अलग इंटरफ़ेस के लिए विषय (एडेप्टी) को एडाप्ट करता है। इस तरह हम ऑब्जेक्ट को नाममात्र के विभिन्न प्रकारों के संग्रह में रख सकते हैं।

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

एडेप्टर अन्य टीमों के अस्थिर कोड से एक टीम को ढालते हैं; अपतटीय टीमों के साथ काम करते समय एक जीवन रक्षक उपकरण ;-)

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

एडाप्टर केवल एकल वंशानुक्रम के जावा सीमा के आसपास प्राप्त करने में मदद करता है। यह एक लिफाफे के तहत कई विशेषणों को संयोजित कर सकता है जो कई उत्तराधिकार की छाप देता है।

कोड वार, एडेप्टर "पतला" है। यह एडेप्टरी क्लास में बहुत अधिक कोड नहीं जोड़ना चाहिए, इसके अलावा केवल एडेपेटी विधि और सामयिक डेटा रूपांतरणों को कॉल करने के लिए आवश्यक है।

JDK या बुनियादी पुस्तकालयों में कई अच्छे एडेप्टर उदाहरण नहीं हैं। अनुप्रयोग डेवलपर्स विशिष्ट इंटरफेस को लागू करने के लिए पुस्तकालयों को अनुकूलित करने के लिए, एडेप्टर बनाते हैं।

डेकोरेटर

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

सज्जाकार आम तौर पर लिपटे हुए, एन्क्रिप्शन, स्वरूपण, या विषय के लिए संपीड़न जैसे लिपटे ऑब्जेक्ट में कार्यक्षमता (पारदर्शी) जोड़ते हैं। यह नई कार्यक्षमता बहुत सारे नए कोड ला सकती है। इसलिए, सज्जाकार आम तौर पर बहुत "मोटी" होते हैं, फिर एडेप्टर।

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

पूरे डेकोरेटर्स परिवार की पाठ्य पुस्तक के उदाहरण JDK - Java IO में आसानी से हैं। सभी वर्ग जैसे BufferedOutputStream , FilterOutputStream और ObjectOutputStream , OutputStream के डेकोरेटर हैं । वे प्याज स्तरित हो सकते हैं, जहां एक से एक डेकोरेटर को फिर से सजाया जाता है, और अधिक कार्यक्षमता जोड़ते हैं।

प्रतिनिधि

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

अधिकांश विशिष्ट उदाहरण दूरस्थ प्रॉक्सी, भारी वस्तु आरंभीकरण और पहुँच प्रॉक्सी हैं।

  • रिमोट प्रॉक्सी - विषय रिमोट सर्वर, विभिन्न JVM या यहां तक ​​कि गैर जावा सिस्टम पर है। प्रॉक्सी RMI / REST / SOAP कॉल या जो कुछ भी आवश्यक है, को कॉल करता है, क्लाइंट को अंतर्निहित तकनीक के संपर्क में आने से बचाता है।

  • आलसी लोड प्रॉक्सी - पूरी तरह से ऑब्जेक्ट को केवल पहले उपयोग या पहले गहन उपयोग को प्रारंभ करें।

  • पहुंच प्रॉक्सी - विषय के लिए नियंत्रण पहुंच।

मुखौटा

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

मुखौटा एक जटिल संरचना को लपेटता है, यह एक सपाट इंटरफ़ेस प्रदान करता है। यह क्लाइंट ऑब्जेक्ट को विषय संरचना में आंतरिक संबंधों के संपर्क में आने से रोकता है इसलिए ढीली युग्मन को बढ़ावा देता है।

पुल

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

कंस्ट्रक्टरों में अंतर

अपने कंस्ट्रक्टरों को देखते समय पैटर्न के अंतर भी स्पष्ट होते हैं।

  • प्रॉक्सी किसी मौजूदा ऑब्जेक्ट को नहीं लपेट रहा है। कंस्ट्रक्टर में कोई विषय नहीं है।

  • डेकोरेटर और एडाप्टर रैप पहले से ही विद्यमान वस्तु है और इसलिए इसे आम तौर पर किया जाता है
    निर्माता में प्रदान की है।

  • मुखौटा निर्माता पूरे ऑब्जेक्ट ग्राफ का मूल तत्व लेता है, अन्यथा यह एडेप्टर के समान दिखता है।

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


30

GoF के कई पैटर्न में ओवरलैप का बहुत बड़ा हाथ है। वे सभी बहुरूपता की शक्ति पर निर्मित हैं और कभी-कभी केवल वास्तव में इरादे में भिन्न होते हैं। (रणनीति बनाम राज्य)

पैटर्न की मेरी समझ हेड फर्स्ट डिज़ाइन पैटर्न पढ़ने के बाद 100 गुना बढ़ गई

मैं इसकी पुरजोर सलाह देता हूँ!


9

विशेषज्ञों के सभी अच्छे उत्तर पहले ही बता चुके हैं कि प्रत्येक पैटर्न का क्या अर्थ है।

मैं प्रमुख बिंदुओं को सजाऊंगा

डेकोरेटर:

  1. रन टाइम में ऑब्जेक्ट में व्यवहार जोड़ें । इनहेरिटेंस इस कार्यक्षमता को प्राप्त करने की कुंजी है, जो इस पैटर्न का लाभ और नुकसान दोनों है।
  2. यह इंटरफ़ेस के व्यवहार को संशोधित करता है।

उदाहरण के लिए (चेनिंग के साथ): java.ioपैकेज क्लासेस संबंधित InputStreamऔर OutputStreamइंटरफेस

FileOutputStream fos1 = new FileOutputStream("data1.txt");  
ObjectOutputStream out1 = new ObjectOutputStream(fos1);

प्रॉक्सी:

  1. आलसी आरंभीकरण के लिए इसका उपयोग करें, ऑब्जेक्ट को कैशिंग और क्लाइंट / कॉलर तक पहुंच को नियंत्रित करके प्रदर्शन में सुधार । यह वैकल्पिक व्यवहार प्रदान कर सकता है या वास्तविक वस्तु कह सकता है। इस प्रक्रिया के दौरान, यह नई वस्तु बना सकता है।
  2. डेकोरेटर के विपरीत , जो वस्तुओं की चेनिंग की अनुमति देता है, प्रॉक्सी छेनी की अनुमति नहीं देता है।

जैसे: java.rmiपैकेज कक्षाएं।

एडाप्टर:

  1. यह दो असंबंधित इंटरफेस को विभिन्न वस्तुओं के माध्यम से एक साथ काम करने की अनुमति देता है , संभवतः एक ही भूमिका निभा रहा है।
  2. यह मूल इंटरफ़ेस को संशोधित करता है

उदाहरण java.io.InputStreamReader( InputStreamरिटर्न Reader)

पुल:

  1. यह अमूर्त और कार्यान्वयन दोनों को स्वतंत्र रूप से भिन्न करने की अनुमति देता है
  2. यह वंशानुक्रम पर रचना का उपयोग करता है ।

जैसे संग्रह कक्षाएं java.utilListद्वारा कार्यान्वित किया गया ArrayList

मुख्य नोट:

  1. एडेप्टर अपने विषय के लिए एक अलग इंटरफ़ेस प्रदान करता है। प्रॉक्सी समान इंटरफ़ेस प्रदान करता है। डेकोरेटर एक बढ़ाया इंटरफ़ेस प्रदान करता है।
  2. एडॉप्टर एक ऑब्जेक्ट का इंटरफ़ेस बदलता है, डेकोरेटर किसी ऑब्जेक्ट की जिम्मेदारियों को बढ़ाता है।
  3. डेकोरेटर और प्रॉक्सी के अलग-अलग उद्देश्य हैं लेकिन समान संरचनाएं हैं
  4. एडेप्टर चीजों को डिज़ाइन करने के बाद काम करते हैं; ब्रिज बनने से पहले वे उन्हें काम करते हैं।
  5. पुल अप-फ्रंट डिज़ाइन किया गया है ताकि अमूर्त और कार्यान्वयन स्वतंत्र रूप से भिन्न हो सकें। असंबंधित वर्गों को एक साथ काम करने के लिए एडॉप्टर को रेट्रोफिटेड किया जाता है
  6. डेकोरेटर को उपवर्ग के बिना वस्तुओं में जिम्मेदारियों को जोड़ने के लिए डिज़ाइन किया गया है।

विभिन्न डिजाइन पैटर्न के उदाहरणों के बारे में महान एसई प्रश्नों / लेखों पर एक नज़र डालें

डेकोरेटर पैटर्न का उपयोग कब करें?

आप ब्रिज पैटर्न का उपयोग कब करते हैं? यह एडेप्टर पैटर्न से कैसे अलग है?

प्रॉक्सी और डेकोरेटर पैटर्न के बीच अंतर


8

वे काफी समान हैं, और उनके बीच की रेखाएं काफी ग्रे हैं। मेरा सुझाव है कि आप सी 2 विकी में प्रॉक्सी पैटर्न और डेकोरेटर पैटर्न प्रविष्टियों को पढ़ें ।

वहाँ की प्रविष्टियाँ और चर्चाएँ काफी व्यापक हैं, और वे अन्य प्रासंगिक लेखों से भी जुड़ती हैं। वैसे, अलग-अलग पैटर्न के बीच बारीकियों के बारे में सोचने पर सी 2 विकी उत्कृष्ट है।

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


4

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

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

और आंतरिक और बाहरी वस्तुओं के बीच इंटरफ़ेस भिन्नता द्वारा:

  • में प्रॉक्सी इंटरफेस एक ही हैं।
  • में डेकोरेटर इंटरफेस समान हैं।
  • में एडाप्टर इंटरफेस औपचारिक रूप से अलग हैं, लेकिन एक ही उद्देश्य को पूरा।
  • में पुल इंटरफेस धारणात्मक अलग हैं।

4

यह हेड फ़र्स्ट डिज़ाइन पैटर्न का उद्धरण है

परिभाषाएँ पुस्तक के अंतर्गत आती हैं। उदाहरण मेरा है।

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

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

मुखौटा - एक इंटरफ़ेस को सरल बनाता है। मान लें कि आपके पास कार, हवाई जहाज, जहाज के इंटरफेस हैं। वास्तव में आप सभी की जरूरत एक ऐसा वर्ग है जो लोगों को एक स्थान से दूसरे स्थान पर भेजता है। आप यह तय करना चाहते हैं कि किस वाहन का उपयोग करना है। फिर आप उन सभी इंटरफ़ेस संदर्भों को 1 छतरी के नीचे इकट्ठा करते हैं और इसे सरल रखने के लिए निर्णय / प्रतिनिधि करते हैं।

हेड फर्स्ट: "एक मुखौटा न केवल एक इंटरफ़ेस को सरल करता है, यह घटकों के एक सबसिस्टम से एक क्लाइंट को डिकॉय करता है। चेहरे और एडेप्टर कई वर्गों को लपेट सकते हैं, लेकिन एक मुखौटा का इरादा सरल करना है, जबकि एक एडाप्टर इंटरफ़ेस को कुछ अलग करने के लिए है। "


1

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


क्या यह सिर्फ एडॉप्टर पैटर्न नहीं होगा?
चार्ल्स ग्राहम

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

1

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

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

एक और बात, एक प्रॉक्सी ठीक वही करता है जो एक लक्ष्य करता है जबकि अन्य पैटर्न लक्ष्य के लिए अधिक कार्यक्षमता जोड़ते हैं।


1

मैं बिल करविंग उत्तर (जो कि महान btw है।) के उदाहरणों को जोड़ना चाहता हूं। मैं कार्यान्वयन के कुछ महत्वपूर्ण अंतर भी जोड़ता हूं, मुझे लगता है कि वे गायब हैं।

उद्धृत भाग [ https://stackoverflow.com/a/350471/1984346] (बिल करविंग) के उत्तर से हैं

प्रॉक्सी, डेकोरेटर, एडेप्टर, और ब्रिज एक वर्ग को "लपेटने" पर सभी विविधताएं हैं। लेकिन उनके उपयोग अलग हैं।

  • प्रॉक्सी का उपयोग तब किया जा सकता है जब आप किसी ऑब्जेक्ट को आलसी-इंस्टेंट करना चाहते हैं, या इस तथ्य को छिपाना चाहते हैं कि आप दूरस्थ सेवा को कॉल कर रहे हैं, या ऑब्जेक्ट तक पहुंच को नियंत्रित करते हैं।

ProxyClass और ObjectClass जो कि अनुमानित है, को एक ही इंटरफ़ेस लागू करना चाहिए, इसलिए वे विनिमेय हैं

उदाहरण - प्रॉक्सी महंगी वस्तु

class ProxyHumanGenome implements GenomeInterface  {
    private $humanGenome = NULL; 

    // humanGenome class is not instantiated at construct time
    function __construct() {
    }

    function getGenomeCount() {
        if (NULL == $this->humanGenome) {
            $this->instantiateGenomeClass(); 
        }
        return $this->humanGenome->getGenomeCount();
    }
} 
class HumanGenome implement GenomeInterface { ... }
  • डेकोरेटर को "स्मार्ट प्रॉक्सी" भी कहा जाता है। इसका उपयोग तब किया जाता है जब आप किसी ऑब्जेक्ट में कार्यक्षमता जोड़ना चाहते हैं, लेकिन उस ऑब्जेक्ट के प्रकार का विस्तार करके नहीं। यह आपको रनटाइम पर ऐसा करने की अनुमति देता है।

डेकोरेटरक्लास को ऑब्जेक्टक्लास के विस्तारित इंटरफेस को लागू करना चाहिए। तो ObjectClass को डेकोरेटरक्लास द्वारा प्रतिस्थापित किया जा सकता है, लेकिन इसके विपरीत नहीं।

उदाहरण - जोड़ कार्यक्षमता जोड़ना

class DecoratorHumanGenome implements CheckGenomeInterface  {

    // ... same code as previous example

    // added functionality
    public function isComplete() {
        $this->humanGenome->getCount >= 21000
    }
}

interface CheckGenomeInterface extends GenomeInterface {

    public function isComplete();

}

class HumanGenome implement GenomeInterface { ... }
  • एडेप्टर का उपयोग तब किया जाता है जब आपके पास एक सार इंटरफ़ेस होता है, और आप उस इंटरफ़ेस को किसी अन्य ऑब्जेक्ट पर मैप करना चाहते हैं जिसमें समान कार्यात्मक भूमिका होती है, लेकिन एक अलग इंटरफ़ेस।

आरोपण अंतर प्रॉक्सी, डेकोरेटर, एडेप्टर

एडेप्टर अपने विषय के लिए एक अलग इंटरफ़ेस प्रदान करता है। प्रॉक्सी समान इंटरफ़ेस प्रदान करता है। डेकोरेटर एक बढ़ाया इंटरफ़ेस प्रदान करता है।

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

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

इस उत्तर की अधिकांश जानकारी https://sourcemaking.com/design_patterns से है , जिसे मैं डिज़ाइन पैटर्न के लिए एक उत्कृष्ट संसाधन के रूप में सुझाता हूँ।


0

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            /* Proxy */

            Console.WriteLine(Environment.NewLine);
            Console.WriteLine("PROXY");
            Console.WriteLine(Environment.NewLine);

            //instead of creating here create using a factory method, the facory method will return the proxy
            IReal realProxy = new RealProxy();
            Console.WriteLine("calling do work with the proxy object ");
            realProxy.DoWork();

            Console.WriteLine(Environment.NewLine);
            Console.WriteLine("ADAPTER");
            Console.WriteLine(Environment.NewLine);

            /*Adapter*/
            IInHand objectIHave = new InHand();
            Api myApi = new Api();
            //myApi.SomeApi(objectIHave); /*I cant do this, use a adapter then */
            IActual myAdaptedObject = new ActualAdapterForInHand(objectIHave);
            Console.WriteLine("calling api with  my adapted obj");
            myApi.SomeApi(myAdaptedObject);


            Console.WriteLine(Environment.NewLine);
            Console.WriteLine("DECORATOR");
            Console.WriteLine(Environment.NewLine);

            /*Decorator*/
            IReady maleReady = new Male();
            Console.WriteLine("now male is going to get ready himself");
            maleReady.GetReady();

            Console.WriteLine(Environment.NewLine);

            IReady femaleReady = new Female();
            Console.WriteLine("now female is going to get ready her self");
            femaleReady.GetReady();

            Console.WriteLine(Environment.NewLine);

            IReady maleReadyByBeautician = new Beautician(maleReady);
            Console.WriteLine("now male is going to get ready by beautician");
            maleReadyByBeautician.GetReady();

            Console.WriteLine(Environment.NewLine);

            IReady femaleReadyByBeautician = new Beautician(femaleReady);
            Console.WriteLine("now female is going to get ready by beautician");
            femaleReadyByBeautician.GetReady();

            Console.WriteLine(Environment.NewLine);

            Console.ReadLine();


        }
    }

    /*Proxy*/

    public interface IReal
    {
        void DoWork();
    }

    public class Real : IReal
    {
        public void DoWork()
        {
            Console.WriteLine("real is doing work ");
        }
    }


    public class RealProxy : IReal
    {
        IReal real = new Real();

        public void DoWork()
        {
            real.DoWork();
        }
    }

    /*Adapter*/

    public interface IActual
    {
        void DoWork();
    }

    public class Api
    {
        public void SomeApi(IActual actual)
        {
            actual.DoWork();
        }
    }

    public interface IInHand
    {
        void DoWorkDifferently();
    }

    public class InHand : IInHand
    {
        public void DoWorkDifferently()
        {
            Console.WriteLine("doing work slightly different ");
        }
    }

    public class ActualAdapterForInHand : IActual
    {
        IInHand hand = null;

        public ActualAdapterForInHand()
        {
            hand = new InHand();
        }

        public ActualAdapterForInHand(IInHand hnd)
        {
            hand = hnd;
        }

        public void DoWork()
        {
            hand.DoWorkDifferently();
        }
    }

    /*Decorator*/

    public interface IReady
    {
        void GetReady();
    }

    public class Male : IReady
    {
        public void GetReady()
        {
            Console.WriteLine("Taking bath.. ");
            Console.WriteLine("Dress up....");
        }
    }

    public class Female : IReady
    {
        public void GetReady()
        {
            Console.WriteLine("Taking bath.. ");
            Console.WriteLine("Dress up....");
            Console.WriteLine("Make up....");
        }
    }

    //this is a decorator
    public class Beautician : IReady
    {
        IReady ready = null;

        public Beautician(IReady rdy)
        {
            ready = rdy;
        }

        public void GetReady()
        {
            ready.GetReady();
            Console.WriteLine("Style hair ");

            if (ready is Female)
            {
                for (int i = 1; i <= 10; i++)
                {
                    Console.WriteLine("doing ready process " + i);
                }

            }
        }
    }

}

-3

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

इसलिए ठोस desighn सिद्धांतों, स्वच्छ कोडिंग सिद्धांतों और ttd पर अधिक ध्यान केंद्रित करें


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