आप एक ही वस्तु के दो संदर्भ कब चाहते हैं?


20

जावा में विशेष रूप से, लेकिन अन्य भाषाओं में भी संभावना है: एक ही वस्तु के दो संदर्भ होने पर यह कब उपयोगी होगा?

उदाहरण:

Dog a = new Dog();
Dob b = a;

क्या ऐसी स्थिति है जहां यह उपयोगी होगा? aजब भी आप उस वस्तु का प्रतिनिधित्व करना चाहते हैं, तो इसका उपयोग करना एक पसंदीदा समाधान क्यों होगा a?


यह फ्लाईवेट पैटर्न के पीछे का सार है ।

@MichaelT क्या आप विस्तृत कर सकते हैं?
२27 बजे बेसिनटर

7
यदि aऔर b हमेशा उसी का संदर्भ लें Dog, तो इसका कोई मतलब नहीं है। यदि वे कभी-कभी हो सकते हैं, तो यह काफी उपयोगी है।
गाबे

जवाबों:


45

एक उदाहरण तब होता है जब आप एक ही वस्तु को दो अलग-अलग सूचियों में रखना चाहते हैं :

Dog myDog = new Dog();
List dogsWithRabies = new ArrayList();
List dogsThatCanPlayPiano = new ArrayList();

dogsWithRabies.add(myDog);
dogsThatCanPlayPiano.add(myDog);
// Now each List has a reference to the same dog

एक और उपयोग तब होता है जब आपके पास एक ही वस्तु कई भूमिकाएं निभाती है :

Person p = new Person("Bruce Wayne");
Person batman = p;
Person ceoOfWayneIndustries = p;

4
मुझे खेद है लेकिन मेरा मानना ​​है कि आपके ब्रूस वेन उदाहरण के लिए एक डिजाइन दोष है, बैटमैन और सीओओ स्थिति आपके व्यक्ति के लिए भूमिका होनी चाहिए।
सिल्वियु बर्किया

44
-1 बैटमैन की गुप्त पहचान का खुलासा करने के लिए।
Ampt

2
@ सिल्वु बर्सी - मैं दृढ़ता से ब्रूस वेन उदाहरण से सहमत हूं यह एक अच्छा उदाहरण नहीं है। एक तरफ, अगर एक वैश्विक पाठ संपादित ने 'ceoOfWayneInd बनी' और 'बैटमैन' का नाम बदलकर 'p' कर दिया (नाम का कोई टकराव या स्कोप नहीं बदला ), और कार्यक्रम के शब्दार्थ बदल गए, तो उनका कुछ टूट गया है। संदर्भित ऑब्जेक्ट वास्तविक अर्थ का प्रतिनिधित्व करता है, कार्यक्रम के भीतर चर नाम नहीं। अलग-अलग शब्दार्थ होने के लिए, यह या तो एक अलग वस्तु है, या एक संदर्भ (जो पारदर्शी होना चाहिए) की तुलना में अधिक व्यवहार के साथ कुछ द्वारा संदर्भित है, और इसलिए 2+ संदर्भों का उदाहरण नहीं है।
gulmer

2
हालांकि ब्रूस वेन उदाहरण के रूप में लिखा काम नहीं कर सकता, मेरा मानना ​​है कि कहा गया इरादा सही है। शायद एक नजदीकी उदाहरण यह हो सकता है Persona batman = new Persona("Batman"); Persona bruce = new Persona("Bruce Wayne"); Persona currentPersona = batman;- जहां आपके पास कई संभावित मूल्य (या उपलब्ध मूल्यों की सूची) और वर्तमान में सक्रिय / चयनित एक संदर्भ है।
डैन पूजे

1
@gbulmer: मैं कहता हूं कि आपके पास दो वस्तुओं का संदर्भ नहीं हो सकता है; संदर्भ currentPersonaएक वस्तु या दूसरे को इंगित करता है, लेकिन दोनों कभी नहीं। विशेष रूप से, यह आसानी से संभव हो सकता है कि currentPersonaहै कभी नहीं करने के लिए सेट bruce, जिस स्थिति में यह निश्चित रूप से दो वस्तुओं के लिए एक संदर्भ नहीं है। मुझे लगता है कि कहेंगे, मेरे उदाहरण में, दोनों batmanऔर currentPersonaएक ही उदाहरण के लिए संदर्भ होते हैं, लेकिन कार्यक्रम के भीतर अलग अलग अर्थ अर्थ सेवा करते हैं।
डैन पूजई

16

यह वास्तव में आश्चर्यजनक रूप से गहरा सवाल है! आधुनिक C ++ (और आधुनिक C ++ से ली जाने वाली भाषाएं, जैसे कि Rust) का अनुभव बताता है कि बहुत बार, आप ऐसा नहीं चाहते हैं! अधिकांश डेटा के लिए, आपको एकल या अनन्य ("स्वामित्व") संदर्भ चाहिए। यह विचार रैखिक प्रकार की प्रणालियों का एक मुख्य कारण भी है ।

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

void encounter(Dog a) {
  hissAt(a);
}

void hissAt(Dog b) {
  // ...
}

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

Dog a, b;
Dog goodBoy = whoseAGoodBoy ? a : b;
feed(goodBoy);
walk(goodBoy);
pet(goodBoy);

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


3
"कम सामान्य मामला" काफी सामान्य है: आपके पास एक सूची या एक नक्शे में संग्रहित वस्तुएं हैं, जो आप चाहते हैं, उसे पुनः प्राप्त करें और आवश्यक संचालन करें। आप मानचित्र या सूची से उनके संदर्भ नहीं मिटाते हैं।
०४ में SJuan76

1
@ SJuan76 "कम सामान्य मामला" पूरी तरह से स्थानीय चर से लेने के बारे में है, डेटा संरचनाओं से संबंधित कुछ भी अंतिम बिंदु के अंतर्गत आता है।

क्या यह केवल संदर्भ-गणना स्मृति प्रबंधन के कारण केवल एक संदर्भ का आदर्श है? यदि ऐसा है, तो यह ध्यान देने योग्य होगा कि प्रेरणा अलग-अलग कचरा संग्राहकों (जैसे C #, जावा, पायथन) के साथ अन्य भाषाओं के लिए प्रासंगिक नहीं है
MarkJ

@MarkJ रैखिक प्रकार केवल एक आदर्श नहीं है, बहुत मौजूदा कोड अनजाने में इसके अनुरूप है क्योंकि यह काफी कुछ मामलों के लिए शब्दशः सही है। इसमें संभावित प्रदर्शन लाभ हैं (लेकिन न तो संदर्भ गिनती के लिए और न ही GCs को ट्रेस करने के लिए, यह केवल तब मदद करता है जब आप एक अलग रणनीति का उपयोग करते हैं जो वास्तव में उस ज्ञान का लाभ उठाता है जो दोनों रिफॉक्शंस और ट्रेसिंग को छोड़ दें)। अधिक रोचक सरल, निर्धारक संसाधन प्रबंधन के लिए इसका अनुप्रयोग है। RAII और C ++ 11 को शब्दार्थ मानें, लेकिन बेहतर (अधिक बार लागू होता है और गलतियों को कंपाइलर द्वारा पकड़ा जाता है)।

6

अस्थायी चर: निम्नलिखित छद्मकोश पर विचार करें।

Object getMaximum(Collection objects) {
  Object max = null;
  for (Object candidate IN objects) {
    if ((max is null) OR (candidate > max)) {
      max = candidate;
    }
  }
  return max;
}

चर maxऔर candidateएक ही वस्तु को इंगित कर सकते हैं, लेकिन विभिन्न नियमों और अलग-अलग समय का उपयोग करके चर असाइनमेंट बदलता है।


3

अन्य उत्तरों के पूरक के लिए, आप एक ही स्थान से शुरू करते हुए, डेटा संरचना को अलग-अलग तरीके से पार करना चाह सकते हैं। उदाहरण के लिए, यदि आपके पास होता, तो आप BinaryTree a = new BinaryTree(...); BinaryTree b = aपेड़ के सबसे बाएं मार्ग को aऔर उसके सबसे दाहिने रास्ते को नीचे की ओर ले जा सकते थे b, जैसे कि कुछ का उपयोग करना:

while (!a.equals(null) && !b.equals(null)) {
    a = a.left();
    b = b.right();
}

जावा को लिखे हुए कुछ समय हो गया है, ताकि कोड सही या समझदार न हो। इसे स्यूडोकोड के रूप में अधिक लें।


3

यह विधि बहुत बढ़िया है जब आपके पास कई ऑब्जेक्ट होते हैं जो सभी किसी अन्य ऑब्जेक्ट पर वापस कॉल करते हैं जो कि अनजाने में उपयोग किया जा सकता है।

उदाहरण के लिए, यदि आपके पास एक टैब्ड इंटरफ़ेस है तो आपके पास टैब 1, टैब 2 और टैब 3 हो सकता है। आप एक सामान्य चर का उपयोग करने में सक्षम होना चाह सकते हैं, भले ही उपयोगकर्ता आपके कोड को सरल बनाने के लिए किस टैब पर हो और फ्लाई ओवर पर यह पता लगाने में कम हो कि आपका उपयोगकर्ता किस टैब पर है।

Tab Tab1 = new Tab();
Tab Tab2 = new Tab();
Tab Tab3 = new Tab();
Tab CurrentTab = new Tab();

फिर, प्रत्येक गिने हुए टैब पर क्लिक करें, आप टैब को संदर्भित करने के लिए करंटटैब को बदल सकते हैं।

CurrentTab = Tab3;

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


3

ऐसे बहुत से परिदृश्य हैं जिनमें उपयोगी होने के लिए अज्ञात " " का संदर्भ b होना चाहिए a। विशेष रूप से:

  • किसी भी समय आप नहीं जानते कि bसंकलन-समय पर क्या इंगित करता है।
  • किसी भी समय आपको एक संग्रह पर पुनरावृति करने की आवश्यकता है, चाहे वह संकलन समय पर हो या नहीं
  • किसी भी समय आपके पास सीमित गुंजाइश है

उदाहरण के लिए:

पैरामीटर

public void DoSomething(Thing &t) {
}

t एक बाहरी दायरे से एक चर का संदर्भ है।

मान और अन्य सशर्त मान लौटाएँ

Thing a = Thing.Get("a");
Thing b = Thing.Get("b");
Thing biggerThing = Thing.max(a, b);
Thing z = a.IsMoreZThan(b) ? a : b;

biggerThingऔर या zतो प्रत्येक संदर्भ हैं । हम नहीं जानते कि संकलन-समय पर कौन सा।ab

लैम्ब्डा और उनके वापसी मूल्य

Thing t = someCollection.FirstOrDefault(x => x.whatever > 123);

xएक पैरामीटर है (उदाहरण 1 ऊपर), और tएक वापसी मान है (उदाहरण 2 ऊपर)

संग्रह

indexByName.add(t.name, t);
process(indexByName["some name"]);

index["some name"]काफी हद तक, एक अधिक परिष्कृत लग रही है b। यह एक वस्तु का उपनाम है जिसे संग्रह में बनाया और भरा गया था।

लूप्स

foreach (Thing t in things) {
 /* `t` is a reference to a thing in a collection */
}

t एक पुनरावृत्ति (पिछले उदाहरण) द्वारा दिए गए आइटम (उदाहरण 2) के लिए एक संदर्भ है।


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

1
@HCBPshenanigans मुझे आपके द्वारा चयनित उत्तरों को बदलने की उम्मीद नहीं है; लेकिन, मैंने उम्मीद की कि पठनीयता में मदद करूं और चयनित उत्तर से गायब कुछ उपयोग-मामलों को भरने में मदद करूँ।
20

2

यह एक महत्वपूर्ण बिंदु है, लेकिन IMHO समझने लायक है।

सभी OO भाषाएँ हमेशा संदर्भों की प्रतिलिपि बनाती हैं, और कभी भी किसी वस्तु को 'अदृश्य रूप से' कॉपी नहीं करती हैं। यदि OO भाषाएँ किसी अन्य तरीके से काम करती हैं तो कार्यक्रम लिखना अधिक कठिन होगा । उदाहरण के लिए, फ़ंक्शंस और विधियाँ, कभी भी किसी ऑब्जेक्ट को अपडेट नहीं कर सकते हैं। जावा, और अधिकांश OO भाषाओं को महत्वपूर्ण जोड़ा जटिलता के बिना उपयोग करना लगभग असंभव होगा।

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

हर बार जब आप aकिसी अन्य फ़ंक्शन के लिए एक तर्क / पैरामीटर के रूप में पास करते हैं, जैसे कॉल
foo(Dog aDoggy);
या किसी विधि को लागू करने के लिए a, अंतर्निहित प्रोग्राम कोड संदर्भ की एक प्रतिलिपि बनाता है, उसी ऑब्जेक्ट के लिए दूसरा संदर्भ उत्पन्न करने के लिए।

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

इसलिए अधिकांश उपयोगी कार्यक्रमों में, एक ही वस्तु के कई संदर्भ होंगे, क्योंकि अधिकांश ओओ प्रोग्रामिंग भाषाओं का शब्दार्थ है।

अब, अगर हम इसके बारे में सोचते हैं, क्योंकि संदर्भ से गुजरना कई OO भाषाओं में उपलब्ध एकमात्र तंत्र है (C ++ दोनों का समर्थन करता है), हम इसे 'सही' डिफ़ॉल्ट व्यवहार होने की उम्मीद कर सकते हैं।

IMHO, संदर्भों का उपयोग करना कुछ कारणों से सही डिफ़ॉल्ट है:

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

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

तो, IMHO, यह आमतौर पर एक ही वस्तु के लिए कई संदर्भों को समझने के लिए समझ में आता है। असामान्य मामलों में जहां एल्गोरिथम के संदर्भ में इसका कोई मतलब नहीं है, ज्यादातर भाषाएं 'क्लोन' या गहरी प्रतिलिपि बनाने की क्षमता प्रदान करती हैं। हालाँकि यह डिफ़ॉल्ट नहीं है।

मुझे लगता है कि जो लोग तर्क देते हैं कि यह डिफ़ॉल्ट नहीं होना चाहिए एक भाषा का उपयोग कर रहे हैं जो स्वचालित कचरा संग्रह प्रदान नहीं करता है। उदाहरण के लिए, पुराने जमाने सी ++। मुद्दा यह है कि उन्हें 'मृत' वस्तुओं को इकट्ठा करने का एक तरीका खोजने की आवश्यकता है और उन वस्तुओं को पुनः प्राप्त नहीं करना चाहिए जो अभी भी आवश्यक हो सकते हैं; एक ही वस्तु के कई संदर्भ होने से यह कठिन हो जाता है।

मुझे लगता है, अगर C ++ में पर्याप्त रूप से कम लागत वाला कचरा संग्रह था, ताकि सभी संदर्भित वस्तुओं को कचरा एकत्र किया जाए, तो बहुत अधिक आपत्ति हो जाती है। अभी भी कुछ मामले होंगे जहाँ संदर्भ शब्दार्थ की आवश्यकता नहीं है। हालांकि, मेरे अनुभव में, जो लोग उन स्थितियों की पहचान कर सकते हैं, वे आम तौर पर वैसे भी उपयुक्त शब्दार्थ चुनने में सक्षम होते हैं।

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

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

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

किसी भी अन्य शब्दार्थ को संभालना कठिन होगा।

Dog a = new Dog("rover");  // initialise with name 
DogList dl = new DogList()
dl.add(a)
...
a.setOwner("Mr Been")

मेरा सुझाव है कि "रोवर" dlको उन setOwnerकार्यक्रमों से प्रभावित होना चाहिए, जिन्हें लिखना, समझना, डीबग करना या संशोधित करना मुश्किल है। मुझे लगता है कि अधिकांश प्रोग्रामर हैरान या निराश होंगे।

बाद में, कुत्ते को बेच दिया जाता है:

soldDog = dl.lookupOwner("rover", "Mr Been")
soldDog.setOwner("Mr Mcgoo")

इस तरह की प्रोसेसिंग आम और सामान्य है। इसलिए संदर्भ शब्दार्थ डिफ़ॉल्ट हैं क्योंकि यह आमतौर पर सबसे अधिक समझ में आता है।

सारांश: यह हमेशा समझ में आता है कि एक ही वस्तु के कई संदर्भ हैं।


अच्छी बात है, लेकिन यह एक टिप्पणी के रूप में बेहतर है
बासिन्टर

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

1

बेशक, एक अन्य परिदृश्य जहाँ आप के साथ समाप्त हो सकता है:

Dog a = new Dog();
Dog b = a;

जब आप कोड बनाए रखते हैं और bएक अलग कुत्ता, या एक अलग वर्ग हुआ करते थे, लेकिन अब इसकी सेवा ली जाती है a

आम तौर पर, मध्यम अवधि में, आपको aसीधे संदर्भित करने के लिए सभी कोड को फिर से काम करना चाहिए , लेकिन यह सीधे नहीं हो सकता है।


1

आप कभी भी यह चाहेंगे कि आपके कार्यक्रम में एक इकाई को एक से अधिक स्थानों पर मेमोरी में खींचने का मौका है, संभवतः क्योंकि विभिन्न घटक इसका उपयोग कर रहे हैं।

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


0

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


-2

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

उदाहरण के लिए, यदि आपके पास दो टेबल हैं:

कुत्ते:

  • आईडी | मालिक_द | नाम
  • 1 | 1 | बार्क केंट

स्वामी:

  • आईडी | नाम
  • 1 | मुझे
  • 2 | आप

निम्नलिखित कॉल किए जाने पर आपके ORM कई दृष्टिकोण कर सकते हैं:

dog = Dog.find(1)  // fetch1
owner = Owner.find(1) // fetch2
superdog = owner.dogs.first() // fetch3
superdog.name = "Superdog"
superdog.save! // write1
owner = dog.owner // fetch4
owner.name = "Mark"
owner.save! // write2
dog.owner = Owner.find(2)
dog.save! // write3

भोली रणनीति में, मॉडल और संबंधित संदर्भों के लिए सभी कॉल अलग-अलग वस्तुओं को पुनः प्राप्त करते हैं। Dog.find(), Owner.find(), owner.dogs, और dog.ownerएक डेटाबेस में परिणाम के आसपास पहली बार, जिसके बाद वे स्मृति में सहेजे जाते हैं मारा। इसलिए:

  • डेटाबेस को कम से कम 4 बार लाया जाता है
  • dog.owner सुपरडॉग के समान नहीं है।
  • dog.name सुपरडॉग के समान नहीं है
  • डॉग और सुपरडॉग दोनों एक ही पंक्ति में लिखने का प्रयास करते हैं और एक दूसरे के परिणामों को ओवरराइट करेंगे: राइट 3 राइट 1 में नाम परिवर्तन को पूर्ववत कर देगा।

संदर्भ के बिना, आपके पास अधिक भ्रूण हैं, अधिक मेमोरी का उपयोग करें, और पहले के अपडेट को ओवरराइट करने की संभावना का परिचय दें।

मान लीजिए कि आपका ORM जानता है कि कुत्तों की तालिका के पंक्ति 1 के सभी संदर्भ एक ही बात की ओर इशारा करते हैं। फिर:

  • fetch4 को समाप्त किया जा सकता है क्योंकि Owner.find (1) के अनुरूप मेमोरी में कोई ऑब्जेक्ट है। fetch3 का परिणाम अभी भी कम से कम एक सूचकांक स्कैन के रूप में होगा, क्योंकि मालिक के स्वामित्व वाले अन्य कुत्ते हो सकते हैं, लेकिन एक पंक्ति पुनर्प्राप्ति को ट्रिगर नहीं करेंगे।
  • कुत्ता और सुपरडॉग एक ही वस्तु की ओर इशारा करते हैं।
  • dog.name और superdog.name एक ही ऑब्जेक्ट को इंगित करता है।
  • dog.owner और superdog.owner एक ही ऑब्जेक्ट को इंगित करते हैं।
  • राइट 1 में बदलाव को ओवरराइट नहीं करता है।

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

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