2012-03-07 14 views
13

मान लें मैं एक ही विधानसभाएक ही असेंबली में परिपत्र संदर्भ एक बुरी बात है?

public class ParentClass : IDisposable 
{ 
    public ChildClass Child 
    { 
    get { return _child; } 
    } 
} 

public class ChildClass 
{ 
    public ParentClass Parent 
    { 
    get { return _parent; } 
    set { _parent= value; } 
    } 

    public ChildClass (ParentClass parent) 
    { 
    Parent= parent; 
    } 

} 

मुझे सही अगर मैं गलत हूँ में निम्नलिखित वर्गों है, लेकिन यह बुरा डिजाइन है। क्या इससे बाद में मेमोरी लीक या कुछ अन्य असुरक्षित मुद्दों का कारण बन जाएगा? स्पष्ट रूप से कचरा कलेक्टर such kind of circular references को संभालने में सक्षम है।

संपादित

क्या होगा अगर दो वर्गों अंत कुछ अन्य वर्ग में इस तरह इस्तेमाल किया जा रहा है?

ParentClass objP = new ParentClass(); 
ChildClass objC =new ChildClass(objP); 
objP.Child = objC; 

विचार कृपया ....

+9

एक पदानुक्रमित पेड़ डेटा संरचना में (जैसे ' 'ParentProductGroup' प्रॉपर्टी के साथ उत्पाद समूह' वर्ग), यह मेरी राय में पूरी तरह मान्य है। –

+2

मिमी .. मुझे नहीं पता कि "बुरा" यह कैसे है .. यह एक डबल लिंक्ड सूची की परिभाषा है .. और जीसी इसका ख्याल रखता है .. – gbianchi

+2

ओ/आरएम उपकरण हर समय इस तरह कोड उत्पन्न करते हैं। – Steven

उत्तर

18

कचरा कलेक्टर के बारे में चिंता न करें; यह सहजता के साथ मनमानी टोपोलॉजी के साथ संदर्भ ग्राफ को संभालता है। ऑब्जेक्ट्स लिखने के बारे में चिंता करें जो अपने आविष्कारों का उल्लंघन करना आसान बनाकर बग बनाने के लिए खुद को उधार देते हैं।

इसका कारण यह है कि यह जीसी पर जोर दिया एक संदिग्ध डिजाइन नहीं है - यह नहीं है - बल्कि क्योंकि यह लागू नहीं करता वांछित अर्थ अपरिवर्तनीय: कि अगर एक्स वाई की मूल है, तो Y चाहिए एक्स

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

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

(हम इन "लाल" और "हरी" पेड़ कहते हैं क्योंकि जब व्हाइटबोर्ड पर डेटा संरचना ड्राइंग, उन मार्कर रंग हम करते थे।)

using System; 

interface IValue { string Value { get; } } 
interface IParent : IValue { IChild Child { get; } } 
interface IChild : IValue { IParent Parent { get; } } 

abstract class HasValue : IValue 
{ 
    private string value; 
    public HasValue(string value) 
    { 
     this.value = value; 
    } 
    public string Value { get { return value; } } 
} 

sealed class GreenChild : HasValue 
{ 
    public GreenChild(string value) : base(value) {} 
} 

sealed class GreenParent : HasValue 
{ 
    private GreenChild child; 
    public GreenChild Child { get { return child; } } 
    public GreenParent(string value, GreenChild child) : base(value) 
    { 
     this.child = child; 
    } 

    public IParent MakeFacade() { return new RedParent(this); } 

    private sealed class RedParent : IParent 
    { 
     private GreenParent greenParent; 
     private RedChild redChild; 
     public RedParent(GreenParent parent) 
     { 
      this.greenParent = parent; 
      this.redChild = new RedChild(this); 
     } 
     public IChild Child { get { return redChild; } } 
     public string Value { get { return greenParent.Value; } } 

     private sealed class RedChild : IChild 
     { 
      private RedParent redParent; 
      public RedChild(RedParent redParent) 
      { 
       this.redParent = redParent; 
      } 
      public IParent Parent { get { return redParent; } } 
      public string Value 
      { 
       get 
       { 
        return redParent.greenParent.Child.Value; 
       } 
      } 
     } 
    } 
} 
class P 
{ 
    public static void Main() 
    { 
     var greenChild1 = new GreenChild("child1"); 
     var greenParent1 = new GreenParent("parent1", greenChild1); 
     var greenParent2 = new GreenParent("parent2", greenChild1); 

     var redParent1 = greenParent1.MakeFacade(); 
     var redParent2 = greenParent2.MakeFacade(); 

     Console.WriteLine(redParent1.Value); // parent1 
     Console.WriteLine(redParent1.Child.Parent.Value); // parent1 ! 
     Console.WriteLine(redParent2.Value); // parent2 
     Console.WriteLine(redParent2.Child.Parent.Value); // parent2 ! 

     // See how that goes? RedParent1 and RedParent2 disagree on what the 
     // parent of greenChild1 is, **but they are self-consistent**. They 
     // always report that the parent of their child is themselves. 
    } 
} 
+0

क्या आप "मुखौटा" पेड़ का उपयोग/जनरेट करने के तरीके के बारे में अधिक जानकारी में जा सकते हैं? – Brian

+2

@ ब्रायन: निश्चित रूप से, आप यहां जाते हैं। –

+0

यह एक बहुत ही रोचक मॉडल है। मैंने अतीत में कुछ ऐसा किया है जो 'घटना' वर्गों का उपयोग कर वास्तविक वस्तुओं का संदर्भ देता है, लेकिन मैंने 'मुखौटा' विचार के बारे में सोचा नहीं था। क्या इस रिलेशनशिप-मॉडलिंग शैली का नाम है और क्या आप किसी और संदर्भ सामग्री के बारे में जानते हैं? –

2

यह ठीक मुझे लगता है कि है और अगर आप दोनों दिशाओं में संबंध नेविगेट करने में सक्षम होना चाहिए उपयोगी है।

जैसा कि आपने बताया है कि जीसी इसे संभाल सकता है, तो यह एक मुद्दा क्यों होना चाहिए? यदि यह आपको आवश्यक कार्यक्षमता प्रदान करता है, तो यह ठीक होना चाहिए।

आपको गुणों से सावधान रहना चाहिए, यह मानते हुए कि यह हमारे कोड के साथ एक मुद्दा होगा।

+0

धन्यवाद .. मेरे प्रश्न को अपडेट किया गया। तो जिस तरह से मैंने यह दिखाया है कि इसे संभाला जा रहा है, यह सही नहीं होना चाहिए? – user20358

+0

नहीं, लेकिन मैं उदाहरण के शो के बजाए बाल क्लास के निर्माता में मूल वर्ग में बाल संपत्ति सेट कर दूंगा, और यह सुनिश्चित करने के लिए कि रिश्तों को सिंक में रहना है, शायद एसडीओएम चेकिंग कोड जोड़ देगा ... –

+0

किस तरह के मुद्दे क्या गुण सिंक से बाहर हो जाते हैं? वे सिंक से कैसे बाहर जाएंगे? – user20358

3

यह कुल मिलाकर ठीक आईएमओ है।
एमएस उदाहरण के रूप में अधिकांश यूआई नियंत्रण/तत्वों में ऐसा करता है उदा। Form में Controls संग्रह है और उस संग्रह में प्रत्येक नियंत्रण में ParentForm संपत्ति है।

+0

"यहां तक ​​कि एमएस भी ऐसा करता है" का मतलब यह नहीं है कि आपको यह भी करना चाहिए। यह विशेष रूप से फ्रेमवर्क के कुछ पुराने हिस्सों के लिए लागू होता है। – svick

+0

यह वास्तव में सच है, सिर्फ एक उदाहरण देना चाहता था जहां इसे "बड़े पैमाने पर" उपयोग किया जाता है ... – ChrFin

+0

तो यदि ये दो वर्ग थे जिनके माता-पिता के बच्चे के रिश्ते नहीं थे तो इसका मतलब होगा कि कुछ प्रकार की कोड गंध अब यह होगा :) – user20358

11

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

जैसा कि आपने स्वयं को पोस्ट किया है, कचरा कलेक्टर चक्रीय संदर्भों को संभालने में सक्षम है, मुख्य रूप से क्योंकि यह संदर्भ गणना का उपयोग नहीं करता है।

इस तरह की संरचना के साथ एकमात्र "मुद्दा" आम तौर पर केवल यह है कि आप अक्सर सिंक्रनाइज़ेशन के दोनों सिरों को सिंक्रनाइज़ करना चाहते हैं, यानी। चाइल्ड सी और अभिभावक पी को p.Child == c if and only if c.Parent == p दिया गया। आपको यह तय करने की आवश्यकता होगी कि इसे सर्वोत्तम तरीके से कैसे संभालें। उदाहरण के लिए, यदि आपके पास कोई विधि है। एडवर्ड चाइल्ड (चाइल्ड सी) यह न केवल माता-पिता को सेट कर सकता है। सी को चाइल्ड, लेकिन चाइल्ड। माता-पिता को अभिभावक। लेकिन क्या होगा यदि बच्चे। माता-पिता को सीधे सौंपा गया है? वे कुछ प्रश्न हैं जिनसे आपको निपटना पड़ सकता है।

+0

उत्तर के लिए धन्यवाद .. तो जिस तरह से मैंने इसे अपने अद्यतन पोस्ट में प्रदर्शित किया है, वैसे भी यह एक समस्या नहीं होनी चाहिए? – user20358

+0

नहीं, लेकिन जैसा कि मैंने लिखा है, आप यह सुनिश्चित करना चाहते हैं कि रिश्ते के दोनों सिरों को सिंक्रनाइज़ किया गया हो। –

+0

गुणों के सिंक होने से क्या समस्याएं हो सकती हैं? वे सिंक से कैसे बाहर जाएंगे? क्या इस वर्ग के परिपत्र संदर्भ पर कोई असर होगा यदि दो वर्गों के बीच माता-पिता के बच्चे के रिश्ते न हों? जैसे कि ये दो वर्ग अलग-अलग चीजें कर रहे थे और कहते हैं कि एक वर्ग दूसरे उपयोगिता कार्यों को करने के लिए दूसरे का इस्तेमाल करता था। – user20358