2009-08-31 11 views
17

क्या गोलाकार वर्ग निर्भरता कोडिंग शैली बिंदु से खराब हैं?क्या गोलाकार वर्ग निर्भरता कोडिंग शैली बिंदु से खराब हैं?

उदाहरण:

एक डेटाबेस आवेदन हम दो वर्गों, एक एकल डाटाबेस (DBInfo) और एक वर्ग है जो एक डेटाबेस कनेक्शन बना सकते हैं के बारे में एक encapsulating जानकारी में। (ConnFactory)

DBInfo में getConnection विधि है जो कनेक्शन बनाने के लिए ConnFactory का उपयोग करती है। लेकिन ConnFactory को ऐसा करने के लिए DBInfo ऑब्जेक्ट की आवश्यकता है।

इस तरह:

class DBInfo { 
    String name; 
    String connectionUrl; 

    Connection getConnection() { 
     return ConnFactory.getConnection(this); 
    } 
} 


class ConnFactory { 
    Connection getConnection(DBInfo toWhat) { 
     return new Connection(toWhat.connectionUrl); 
    } 
} 

मेरे सह कार्यकर्ता का कहना है कि यह बुरा व्यवहार है और कोई यह बेहतर होगा अगर वहाँ निर्भरता और का केवल एक ही दिशा थे (कोई भी कोडिंग शैलियों पठनीयता के कारण अवहेलना) यहाँ जैसे परिपत्र।

क्या यह बुरा अभ्यास है, विरोधी पैटर्न या कोड गंध है? क्या कोई कमी है?

उत्तर

15

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

ज्यादातर मामलों में मैं दृढ़ता से एक ऐसे डिजाइन पर विचार करता हूं जहां एक परिपत्र निर्भरता आवश्यक नहीं है, लेकिन दुर्लभ मामलों में यह ठीक हो सकता है।

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

+0

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

1

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

4

यह कोड केवल तभी काम करता है जब ConnFactory.getConnection() स्थिर है। एक बेहतर समाधान getConnection()ConnFactory की एक उदाहरण विधि बनाना होगा। फिर आपका डीबीआईएनएफओ ConnFactory को तर्क के रूप में ले सकता है (संभवतः एक कन्स्ट्रक्टर में, यदि आपके पास ओवरलोडेड कन्स्ट्रक्टर है)। हालांकि, मुझे लगता है कि इस मामले के लिए स्थैतिक विधि का उपयोग गोलाकार संदर्भ से अधिक खराब अभ्यास है।

यदि आप इस मार्ग पर जाना चाहते थे, हालांकि, मैं एक इंटरफ़ेस IConnFactory भी बनाउंगा जो DBInfo से बातचीत करेगा और ConnFactory लागू होगा। फिर कोई परिपत्र संदर्भ नहीं है - DBInfo और ConnFactory दोनों IConnFactory पर निर्भर करेगा, जो न तो इस पर निर्भर करेगा।

+0

तो मूल रूप से आप कह रहे हैं, यदि कक्षाएं कसकर युग्मित नहीं हैं, तो परिपत्र निर्भरता ठीक है? –

+3

मुझे लगता है कि इसे डालने का एक तरीका होगा। मुझे लगता है कि मेरा मुद्दा था, यदि आप एक परिपत्र निर्भरता का उपयोग करने के लिए लुभाने वाले हैं, तो संभावना है कि आप (ए) चीजों को बहुत कसकर जोड़ रहे हैं, और (बी) कहीं और कुछ गलत कर रहे हैं। जैसा कि एंटोन गोगोलेव दूसरे जवाब में बताते हैं, आप एकल जिम्मेदारी सिद्धांत का उल्लंघन कर रहे हैं, जो आपकी समस्या को बढ़ाता है। –

+0

@ डैनियल प्राइडन: एकल उत्तरदायित्व सिद्धांत के लिए +1 – Cohen

8

हां, आमतौर पर परिपत्र निर्भरता बोलना बुरा होता है, हालांकि हमेशा बुरा नहीं होता है। परिपत्र निर्भरताओं के साथ समस्याएं तंग युग्मन, पारस्परिक रूप से निर्भर मॉड्यूल और आम तौर पर डोमिनोज़ प्रभाव शामिल करती हैं, जब एक मॉड्यूल में परिवर्तन अन्य मॉड्यूल में फैलता है।

यह कहा गया है कि आपका कोड केवल DBInfo में एकल उत्तरदायित्व सिद्धांत का उल्लंघन कर रहा है न केवल डेटाबेस के बारे में जानकारी संग्रहीत करता है, बल्कि Connection ऑब्जेक्ट्स प्राप्त करने के लिए भी जिम्मेदार है। कार्यक्षमता के उस विशेष टुकड़े को एक अलग वर्ग में हटा दें और सबकुछ ठीक होगा।

0

सर्कुलर निर्भरता बुरा कर रहे हैं क्योंकि:

  • दो निर्भरता एक से अधिक
  • है आप संवर्द्धित (उनमें से एक है, जो छोटे, बारीकी से मिलकर बातों के लिए मूर्खतापूर्ण होगा मजाक के बिना) का परीक्षण नहीं कर सकता।

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

7

नहीं जरूरी

मुझे नहीं लगता कि वर्ग के विवरण का स्तर स्तर पर परिपत्र निर्भरता बुरा कर रहे हैं है। मुझे कोई समस्या नहीं दिखती है यदि दो, तीन या शायद चार वर्ग पारस्परिक रूप से निर्भर हैं। (मैं यह नहीं कह रहा हूं कि यह कुछ है जो आप चाहते हैं, लेकिन कुछ परिस्थितियों में यह ठीक हो सकता है)।

यह एक समस्या है यदि आपके पास ऊपर या नीचे वर्णित सभी कारणों के लिए पैकेज या मॉड्यूल स्तर पर पारस्परिक निर्भरता है।

1

एक ओआरएम परत का उपयोग कर किसी भी अनुप्रयोग में ऐसे सामान्य मामले में एक द्वि-दिशात्मक एक से अधिक संबंधों के बारे में क्या है? क्या यह गोलाकार निर्भरता का मामला नहीं है?

क्या यह खराब/कोड-गंध है?

संबंधित मुद्दे