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


136

क्या आप कोई अच्छी व्याख्या दे सकते हैं कि प्रॉक्सी और डेकोरेटर में क्या अंतर है ?

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

सवाल यह है कि - क्या प्रॉक्सी बनाया के साथ एकत्रीकरण अब भी है प्रॉक्सी या बल्कि डेकोरेटर ? एकत्रीकरण के साथ प्रॉक्सी बनाने के लिए क्या इसकी अनुमति (GoF पैटर्न में परिभाषा के अनुसार) है ?



5
आपको यह विचार कहाँ से मिला कि प्रॉक्सी प्रॉक्सी का उपयोग करता है और डेकोरेटर एकत्रीकरण का उपयोग करता है?
CPerkins

1
@CPerkins राहुल त्रिपाठी के जवाब के लिए मेरी टिप्पणी देखें।
सुकस रोसझोटारस्की

1
और डेकोरेटर ( पैटर्न ।cs.up.ac.za/examples/ch2/decorator-theory.cs ) - स्पष्ट रूप से एकत्रीकरण, प्रॉक्सी ( प्रतिमान .cs.up.ac.za/examples/ch2-proxy-theory.cs ) - जाहिर है रचना।
संकरकोव

जवाबों:


17

यहाँ GoF (पृष्ठ २१६) से प्रत्यक्ष उद्धरण है।

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

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

लोकप्रिय उत्तरों से संकेत मिलता है कि एक प्रॉक्सी अपने प्रतिनिधि के ठोस प्रकार को जानता है। इस उद्धरण से हम देख सकते हैं कि हमेशा सच नहीं होता है।

GoF के अनुसार प्रॉक्सी और डेकोरेटर के बीच अंतर यह है कि प्रॉक्सी क्लाइंट को प्रतिबंधित करता है। डेकोरेटर नहीं करता। कार्यक्षमता में पहुँच को नियंत्रित करके ग्राहक जो कुछ करता है उसे प्रॉक्सी प्रतिबंधित कर सकता है ; या यह प्रतिबंधित हो सकता है कि एक ग्राहक ग्राहक को अदृश्य और अज्ञात कार्यों को करने से क्या जानता है। डेकोरेटर इसके विपरीत करता है: यह इस बात को बढ़ाता है कि इसका प्रतिनिधि ग्राहकों के लिए एक तरह से क्या करता है।

हम कह सकते हैं कि प्रॉक्सी एक ब्लैक बॉक्स है जबकि डेकोरेटर एक सफेद बॉक्स है।

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

  • डेकोरेटर अपने क्लाइंट को सूचित और सशक्त बनाता है।
  • प्रॉक्सी अपने ग्राहक को प्रतिबंधित और अक्षम करता है।

113

वास्तविक अंतर स्वामित्व (संरचना बनाम एकत्रीकरण) नहीं है, बल्कि टाइप-जानकारी है।

एक डेकोरेटर है हमेशा अपने delegatee पारित कर दिया। एक प्रॉक्सी इसे स्वयं बना सकता है , या वह इसे इंजेक्ट कर सकता है।

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

एक गतिशील भाषा में, यदि प्रतिनिधि को इंजेक्ट किया जाता है और एक ही इंटरफ़ेस होता है, तो कोई अंतर नहीं है।

आपके प्रश्न का उत्तर है - हां"।


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

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

85

डेकोरेटर पैटर्न गतिशील रूप से ऑब्जेक्ट में फ़ंक्शंस जोड़ने पर केंद्रित है, जबकि प्रॉक्सी पैटर्न किसी ऑब्जेक्ट तक पहुंच को नियंत्रित करने पर केंद्रित है।

संपादित करें: -

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


5
एक प्रॉक्सी अभी भी कार्यक्षमता जोड़ने के लिए इस्तेमाल किया जा सकता है। AOP प्रॉक्सी के बारे में सोचो।
सोतीरियोस डेलिमोलिसिस 4'13

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

इस मामले में जब छद्म में उदाहरण 'छिपा' होता है, तो मेरे लिए भिन्नता स्पष्ट होती है (जैसा कि मैंने लिखा है) लेकिन मुझे लगता है कि अक्सर लोग प्रॉक्सी कक्षाओं के रूप में कॉल करते हैं जो प्रॉक्सी ऑब्जेक्ट ले जाते हैं जो कि कंस्ट्रक्टर पैरामीटर के रूप में पारित किया गया था। इस मामले में नई कार्यक्षमता जोड़ने या नियंत्रित करने का अंतर मेरे लिए (बहुत) पतला है।
ुकाज़ रेज़्ज़ोटरस्की

5
एक प्रॉक्सी और वास्तविक विषय के बीच संबंध आम तौर पर संकलन समय पर निर्धारित किया जाता है, प्रॉक्सी किसी तरह से इसे लागू करता है, जबकि डेकोरेटर या एडेप्टर केवल विषय के इंटरफ़ेस को जानते हुए, रनटाइम पर विषय को सौंपा जाता है। आशा है कि समझ में आता है !!! :)
राहुल त्रिपाठी

1
क्या आप इस लाइन को अपने उत्तर में जोड़ सकते हैं।
सुकस रोसझोटारस्की

49

डेकोरेटर को सजे हुए ऑब्जेक्ट (आमतौर पर कंस्ट्रक्टर के माध्यम से) के लिए संदर्भ मिलता है, जबकि प्रॉक्सी खुद से ऐसा करने के लिए जिम्मेदार है।

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

प्रॉक्सी आमतौर पर सुरक्षा या कैशिंग / लैजिंग को जोड़ने के लिए फ्रेमवर्क द्वारा उपयोग किया जाता है और फ्रेमवर्क द्वारा निर्मित होता है (नियमित डेवलपर द्वारा ही नहीं)।

डेकोरेटर आमतौर पर डेवलपर द्वारा पुराने या विरासत वर्गों के लिए नए व्यवहार को जोड़ने के लिए इस्तेमाल किया जाता है, बल्कि वास्तविक वर्ग के आधार पर (इसलिए यह इंटरफ़ेस उदाहरणों की विस्तृत श्रृंखला पर काम करता है, प्रॉक्सी कंक्रीट क्लास के आसपास है)।


22

मुख्य अंतर:

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

सोर्समेकिंग लेख समानताओं और अंतरों को उत्कृष्ट तरीके से उद्धृत करता है।

संबंधित एसई प्रश्न / लिंक:

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

एडाप्टर और प्रॉक्सी पैटर्न के बीच सटीक अंतर क्या है?


3

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

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


आप क्या कह रहे हैं जो अन्य 4 उत्तरों से पहले से अलग है?
स्टीफन राउच

मुझे नहीं पता कि यह सब वहाँ है या नहीं। मुझे सिर्फ पिछले उत्तरों को पढ़ने के बाद झंकार करने का आग्रह महसूस हुआ।
लिन पर जेम्स लिन

1

इस उत्तर का पता लगाने के लिए कुछ समय लिया और इसका वास्तव में क्या मतलब है। कुछ उदाहरणों से इसे और स्पष्ट होना चाहिए।

Proxy प्रथम:

public interface Authorization {
    String getToken();
} 

तथा :

// goes to the DB and gets a token for example
public class DBAuthorization implements Authorization {
    @Override
    public String getToken() {
        return "DB-Token";
    }
}

और इस का एक कॉलर है Authorization, एक बहुत ही मूक:

class Caller {
    void authenticatedUserAction(Authorization authorization) {
        System.out.println("doing some action with : " + authorization.getToken());
    }
}

अभी तक संयुक्त राष्ट्र के कुछ भी नहीं, सही? एक निश्चित सेवा से एक टोकन प्राप्त करें, उस टोकन का उपयोग करें। अब तस्वीर के लिए एक और आवश्यकता आती है, लॉगिंग जोड़ें: अर्थ हर बार टोकन लॉग करें। यह इस मामले के लिए सरल है, बस एक बनाएं Proxy:

public class LoggingDBAuthorization implements Authorization {

    private final DBAuthorization dbAuthorization = new DBAuthorization();

    @Override
    public String getToken() {
        String token = dbAuthorization.getToken();
        System.out.println("Got token : " + token);
        return token;
    }
}

हम उसका उपयोग कैसे करेंगे?

public static void main(String[] args) {
    LoggingDBAuthorization loggingDBAuthorization = new LoggingDBAuthorization();

    Caller caller = new Caller();
    caller.authenticatedUserAction(loggingDBAuthorization);
}

सूचना है कि LoggingDBAuthorization रखती है का एक उदाहरण DBAuthorization। दोनों LoggingDBAuthorizationऔर DBAuthorization कार्यान्वित Authorization

  • एक प्रॉक्सी DBAuthorizationबेस इंटरफेस ( Authorization) के कुछ ठोस कार्यान्वयन ( ) का आयोजन करेगा । दूसरे शब्दों में एक प्रॉक्सी जानता है कि वास्तव में क्या अनुमानित है।

Decorator:

यह Proxyएक इंटरफ़ेस के साथ बहुत अधिक शुरू होता है :

public interface JobSeeker {
    int interviewScore();
}

और इसका कार्यान्वयन:

class Newbie implements JobSeeker  {
    @Override
    public int interviewScore() {
        return 10;
    }
}

और अब हम एक और अनुभवी उम्मीदवार को जोड़ना चाहते हैं, जो कहते हैं कि यह साक्षात्कार स्कोर है और दूसरे से एक है JobSeeker:

@RequiredArgsConstructor 
public class TwoYearsInTheIndustry implements JobSeeker {

    private final JobSeeker jobSeeker;

    @Override
    public int interviewScore() {
        return jobSeeker.interviewScore() + 20;
    } 
}

ध्यान दें कि मैंने कैसे कहा कि प्लस एक और जॉबसेकर से है , नहीं Newbie । A Decoratorको ठीक से नहीं पता है कि यह क्या सज रहा है, यह उस सजाए गए उदाहरण के अनुबंध को जानता है (इसके बारे में जानता है JobSeeker)। यहाँ ध्यान दें कि यह एक के विपरीत है Proxy; इसके विपरीत, यह जानता है कि वास्तव में यह क्या सजा रहा है।

आप सवाल कर सकते हैं कि क्या वास्तव में इस मामले में दो डिजाइन पैटर्न के बीच कोई अंतर है? क्या होगा अगर हम Decoratorएक के रूप में लिखने की कोशिश की Proxy?

public class TwoYearsInTheIndustry implements JobSeeker {

    private final Newbie newbie = new Newbie();

    @Override
    public int interviewScore() {
        return newbie.interviewScore() + 20;
    }
}

यह निश्चित रूप से एक विकल्प है और हाइलाइट करता है कि ये पैटर्न कितने करीब हैं; वे अभी भी अलग-अलग परिदृश्यों के लिए अभिप्रेत हैं जैसा कि अन्य उत्तरों में बताया गया है।


1

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

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