सिद्धांत 2 में एक प्रॉक्सी क्या है?


112

मैंने अभी सभी डॉक्ट्रिन 2 डॉक्यूमेंट को पढ़ना समाप्त किया है, मैंने अपना सैंडबॉक्स शुरू किया है, मैंने ज्यादातर प्रिंसिपल्स को समझा है, लेकिन अभी भी एक सवाल है और मुझे डॉक में कोई पूर्ण विवरण नहीं मिला है।

  1. Proxyकक्षाएं क्या हैं ?
  2. मुझे इनका उपयोग कब करना चाहिए?

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

जवाबों:


160

अपडेट करें

इस उत्तर में प्रॉक्सी ऑब्जेक्ट और आंशिक ऑब्जेक्ट के बीच अंतर के बारे में गलत जानकारी है। अधिक जानकारी के लिए @ Kontrollfreak का उत्तर देखें: https://stackoverflow.com/a/17787070/252591


जब भी आपकी क्वेरी एक इकाई बनाने के लिए आवश्यक सभी डेटा वापस नहीं करती है तो प्रॉक्सी ऑब्जेक्ट का उपयोग किया जाता है। निम्नलिखित परिदृश्य की कल्पना करें:

@Entity
class User {
     @Column protected $id;
     @Column protected $username;
     @Column protected $firstname;
     @Column protected $lastname;

     // bunch of setters/getters here
}

DQL query:

SELECT u.id, u.username FROM Entity\User u WHERE u.id = :id

जैसा कि आप देख सकते हैं कि यह क्वेरी वापस नहीं आती है firstnameऔर lastnameगुण, इसलिए आप Userऑब्जेक्ट नहीं बना सकते हैं । अधूरी इकाई के निर्माण से अप्रत्याशित त्रुटियां हो सकती हैं।

यही कारण है कि डॉक्ट्रिन UserProxyआलसी लोडिंग का समर्थन करने वाली वस्तु का निर्माण करेगा । जब आप firstnameप्रॉपर्टी (जिसे लोड नहीं किया गया है) तक पहुंचने का प्रयास करेंगे, तो यह पहले डेटाबेस से उस मूल्य को लोड करेगा।


मेरा मतलब है कि मुझे प्रॉक्सी का उपयोग क्यों करना चाहिए?

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

आलसी लोडिंग को एंटिटी में ही लागू क्यों नहीं किया जा सकता है?

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

क्या आप मुझे एक उपयोग मामला प्रदान कर सकते हैं?

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

SELECT a.title, a.createdAt
FROM Entity\Article a
ORDER BY a.createdAt DESC
LIMIT 25

$isFirst = true;
foreach ($articles as $article) {
    echo $article->getTitle();
    echo $article->getCreatedAt();

    if ($isFirst) {
        echo $article->getContent(); // Article::content is not loaded so it is transparently loaded 
                                     // for this single article.

        $isFirst = false;
    }
}

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

1
आंशिक वस्तुएं और छद्म वस्तुएं समान हैं - उन्हें समानार्थक शब्द माना जा सकता है। बाकी प्रश्नों के लिए मेरे अपडेट किए गए उत्तर की जांच करें।
क्रुज़िन

1
मुझे समझ में नहीं आता है कि क्यों सिद्धांत वस्तु का निर्माण नहीं कर सकता है यदि इसमें केवल आधे गुण हैं। Php में मैं एक ऑब्जेक्ट बनाने में सक्षम हूँ, भले ही मैं सभी गुण सेट न करूँ।
सैंडर्स

1
यह एक पूरी तरह से भयानक जवाब है और दस्तावेज में होना चाहिए।
जिम्बो

7
इस उत्तर में परदे के पीछे और आंशिक वस्तुओं की कुछ गंभीर गलतफहमियाँ हैं। क्यों समझने के लिए मेरा जवाब देखें ।
Kontrollfreak

81

प्रॉक्सी

एक डॉक्ट्रिन प्रॉक्सी सिर्फ एक आवरण है जो इसके लिए आलसी लोडिंग प्रदान करने के लिए एक इकाई वर्ग का विस्तार करता है।

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

यह इस तथ्य के कारण आपके आवेदन के लिए पूरी तरह से पारदर्शी होता है कि प्रॉक्सी आपके इकाई वर्ग का विस्तार करता है।

यदि आप JOINउन्हें अपनी क्वेरी में नहीं रखते हैं या लाने के लिए मोड सेट करते हैं, तो डॉक्ट्रीन डिफ़ॉल्ट लोड प्रॉक्सिज़ के रूप में डिफ़ॉल्ट हाइड्रेट संघों द्वारा करेगा EAGER


अब मुझे इसे जोड़ना होगा क्योंकि मेरे पास हर जगह टिप्पणी करने के लिए पर्याप्त प्रतिष्ठा नहीं है:

दुर्भाग्य से, क्रोज़िन के उत्तर में गलत सूचना है।

यदि आप DQL क्वेरी को निष्पादित करते हैं, जैसे

SELECT u.id, u.username FROM Entity\User u WHERE u.id = :id

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

इसे ध्यान में रखते हुए, एक निष्कर्ष पर पहुंचता है कि उपयोग के मामले का उदाहरण या तो काम नहीं करेगा। $articleऑब्जेक्ट के रूप में एक्सेस करने के लिए DQL को कुछ इस तरह बदलना होगा :

SELECT a FROM Entity\Article a ORDER BY a.createdAt DESC LIMIT 25

और सभी 25 संस्थाओं getContent()की सामग्री संपत्तियों को लोड नहीं करने के लिए एसोसिएशन द्वारा लौटा दी गई संपत्ति एक संघ होना चाहिए ।


आंशिक वस्तुएं

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

SELECT partial u.{id, username} FROM Entity\User u WHERE u.id = :id

यह आपको आंशिक रूप से भरी हुई इकाई वस्तु देता है।

लेकिन सावधान रहें कि आंशिक वस्तुएं समीप नहीं हैं! आलसी लोडिंग उन पर लागू नहीं होती है। इसलिए, आंशिक वस्तुओं का उपयोग करना आम तौर पर खतरनाक है और इससे बचा जाना चाहिए। और पढ़ें: आंशिक वस्तुएं - सिद्धांत 2 ओआरएम 2 प्रलेखन


1
धन्यवाद, यह इस बारे में और अधिक विवरण प्रदान करता है कि स्वीकृत उत्तर की तुलना में सिद्धांत कैसे प्रॉक्सिस और आंशिक वस्तुओं का उपयोग करता है! और डॉक्स का संदर्भ सहायक भी है।
बीन

1
संदर्भ के लिए, यहाँ प्रॉक्सी ऑब्जेक्ट्स के बारे में डॉक्स का अनुभाग: doctrine-orm.readthedocs.org/en/latest/reference/…
सेम

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