क्या युग्मन को बढ़ाए बिना DRY लागू करना संभव है?


14

मान लें कि हमारे पास एक सॉफ्टवेयर मॉड्यूल है जो एक फ़ंक्शन एफ को लागू करता है। एक अन्य मॉड्यूल बी एफ के समान फ़ंक्शन को लागू करता है।

डुप्लिकेट कोड से छुटकारा पाने के कई तरीके हैं:

  1. B से A का उपयोग F करें।
  2. B, A से F का उपयोग करते हैं।
  3. F को अपने स्वयं के मॉड्यूल C में रखें और A और B दोनों को इसका उपयोग करने दें।

ये सभी विकल्प मॉड्यूल के बीच अतिरिक्त निर्भरता उत्पन्न करते हैं। वे युग्मन की लागत पर DRY सिद्धांत को लागू करते हैं।

जहां तक ​​मैं देख सकता हूं, DRY लागू करते समय युग्मन हमेशा बढ़ जाता है या उच्च स्तर पर ले जाया जाता है। सॉफ्टवेयर डिजाइन के दो सबसे बुनियादी सिद्धांतों के बीच एक संघर्ष प्रतीत होता है।

(वास्तव में मुझे यह आश्चर्यजनक नहीं लगता है कि इस तरह के संघर्ष होते हैं। यह शायद वही है जो अच्छे सॉफ़्टवेयर डिज़ाइन को इतना कठिन बना देता है। मुझे यह आश्चर्यजनक लगता है कि इन संघर्षों को आम तौर पर परिचयात्मक ग्रंथों में संबोधित नहीं किया जाता है।)

संपादित करें (स्पष्टीकरण के लिए): मेरा मानना ​​है कि एफ और एफ 'की समानता केवल एक संयोग नहीं है। यदि F को संशोधित करना होगा, तो F 'को उसी तरह से संशोधित करना होगा।


2
... मुझे लगता है कि DRY एक बहुत ही उपयोगी रणनीति हो सकती है, लेकिन यह प्रश्न DRY के साथ अक्षमता दर्शाता है। कुछ (जैसे, OOP उत्साही) तर्क दे सकते हैं कि आपको A और B की वैचारिक स्वायत्तता को बनाए रखने के लिए F को B में कॉपी / पेस्ट करना चाहिए, लेकिन मैं ऐसे परिदृश्य में नहीं भागता जहाँ मैं ऐसा करूँ। मुझे लगता है कि कॉपी / पेस्टिंग कोड सबसे खराब विकल्प के बारे में है, मैं उस "शॉर्ट टर्म मेमोरी लॉस" को महसूस नहीं कर सकता, जहां मुझे बस इतना यकीन था कि मैंने पहले से ही कुछ करने के लिए एक विधि / फ़ंक्शन लिखा था; एक फ़ंक्शन में बग को ठीक करना और दूसरे को अपडेट करने के लिए भूलना एक और प्रमुख मुद्दा हो सकता है।
जूनियर

3
इस OO सिद्धांतों के परस्पर विरोधी हैं। ज्यादातर मामलों में आपको एक उचित व्यापार बंद करना होगा। लेकिन IMHO DRY सिद्धांत सबसे मूल्यवान है। जैसा कि @rrh ने लिखा: एक ही व्यवहार को कई स्थानों पर लागू करना एक रखरखाव बुरा सपना है जिसे किसी भी कीमत पर टाला जाना चाहिए। यह पता लगाना कि आप उत्पादन में निरर्थक प्रतियों में से एक को अपडेट करना भूल गए हैं, अपने व्यवसाय को नीचे ले जा सकते हैं।
तीमुथियुस ट्रक

2
@TimothyTruckle: हमें उन्हें OO सिद्धांत नहीं कहना चाहिए क्योंकि वे अन्य प्रोग्रामिंग प्रतिमानों पर भी लागू होते हैं। और हाँ, DRY मूल्यवान है, लेकिन अधिक खतरनाक भी है। केवल इसलिए नहीं कि यह निर्भरता और इस प्रकार जटिलता पैदा करता है। इसे अक्सर संयोग के कारण होने वाले डुप्लिकेट पर भी लागू किया जाता है जिसके बदलने के अलग-अलग कारण होते हैं।
फ्रैंक पफर

1
... कभी-कभी जब मैंने इस परिदृश्य में भाग लिया है तो मैं एफ को उन हिस्सों में तोड़ने में सक्षम हो गया हूं जो ए की जरूरतों और बी की जरूरत के लिए उपयोग करने योग्य हो सकते हैं।
jrh

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

जवाबों:


14

ये सभी विकल्प मॉड्यूल के बीच अतिरिक्त निर्भरता उत्पन्न करते हैं। वे युग्मन की लागत पर DRY सिद्धांत को लागू करते हैं।

वे हाँ क्यों करते हैं? लेकिन वे लाइनों के बीच युग्मन को कम करते हैं। आपको जो मिल रहा है वह युग्मन को बदलने की शक्ति है। युग्मन कई रूपों में आता है। कोड निकालने से अप्रत्यक्ष और अमूर्तता बढ़ती है। वह बढ़ाना जो अच्छा या बुरा हो सकता है। नंबर एक चीज जो यह तय करती है कि आपको जो नाम मिलता है वह वह नाम है जो आप इसके लिए उपयोग करते हैं। अगर नाम देखकर मुझे आश्चर्य होता है जब मैं अंदर देखता हूं तो आपने किसी का एहसान नहीं किया है।

इसके अलावा, वैक्यूम में DRY का पालन न करें। यदि आप दोहराव को मारते हैं तो आप यह अनुमान लगाने की जिम्मेदारी ले रहे हैं कि उस कोड के ये दो उपयोग एक साथ बदल जाएंगे। यदि वे स्वतंत्र रूप से बदलने की संभावना रखते हैं, तो आपको भ्रम की स्थिति पैदा होती है और कम लाभ के लिए अतिरिक्त काम होता है। लेकिन वास्तव में अच्छा नाम ही इसे और अधिक स्वादिष्ट बना सकता है। यदि आप सभी सोच सकते हैं कि एक बुरा नाम है, तो कृपया, अभी रुकें।

युग्मन हमेशा मौजूद रहेगा जब तक कि आपका सिस्टम इतना अलग-थलग न हो कि कोई भी कभी भी यह नहीं जान पाएगा कि यह काम करता है या नहीं। तो कपलिंग को रिफ्लेक्ट करना आपके जहर को चुनने का खेल है। DRY के बाद कई जगहों पर एक ही डिज़ाइन के निर्णय को बढ़ाकर बनाई गई युग्मन को कम करके भुगतान कर सकते हैं जब तक कि इसे बदलना बहुत मुश्किल न हो। लेकिन DRY आपके कोड को समझना असंभव बना सकता है। उस स्थिति को उबारने का सबसे अच्छा तरीका वास्तव में एक अच्छा नाम है। यदि आप एक अच्छे नाम के बारे में नहीं सोच सकते हैं, तो मुझे उम्मीद है कि आप व्यर्थ नामों से बचने में कुशल होंगे


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

1
कोई बात नहीं, मेरा बुरा: meta.stackexchange.com/a/263672/143358
बसिलेव्स

@FrankPuffer बेहतर है?
candied_orange

3

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

शीर्षक का जवाब देने के लिए - हाँ, यह संभव है, लेकिन रनटाइम प्रेषण के परिणामों के लिए तैयार रहें।

  • में एफ को परिभाषित करें , एफ की कार्यक्षमता प्रदान करें
  • बी में इंटरफ़ेस एफ को परिभाषित करें
  • सी में एफ डालें
  • सभी निर्भरता को प्रबंधित करने के लिए मॉड्यूल डी बनाएं (यह ए, बी और सी पर निर्भर करता है)
  • एफ के लिए एफ अनुकूल एक और एफ बी डी में
  • A और B के आवरण (पास) आवरण

इस तरह, आपके पास एक ही प्रकार की निर्भरताएँ होती हैं जो कि एक दूसरे मॉड्यूल पर निर्भर करती हैं।

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


1
+1, लेकिन स्पष्ट चेतावनी के साथ कि यह आमतौर पर एक बुरा व्यापार है। वह स्थैतिक सुरक्षा आपकी सुरक्षा के लिए है, और कुछ दूरी पर डरावना कार्रवाई के एक समूह के साथ इसे दरकिनार करते हुए बस हार्ड-टू-ट्रैक डाउन-डाउन बग के लिए पूछ रहा है जब आपकी परियोजना की जटिलता थोड़ी बढ़ जाती है ...
मेसन व्हीलर

1
क्या वाकई डीआई को डिप्रेशन तोड़ने के लिए कहा जा सकता है? औपचारिक रूप से भी, आपको इसे लागू करने के लिए F के हस्ताक्षर के साथ एक इंटरफ़ेस की आवश्यकता है। लेकिन फिर भी, अगर मॉड्यूल एक rwally एफ सी से यह उस पर depwnds, सी की परवाह किए बिना उपयोग कर रहा है कार्यावधि में इंजेक्ट किया जा रहा है या सीधे linked.DI निर्भरता को तोड़ने नहीं करता है, केवल विफलता आस्थगित करें बग dependenc प्रदान नहीं की है, तो
max630

@ max630 यह कार्यान्वयन निर्भरता को संविदात्मक के साथ बदल देता है, जो कमजोर है।
बसिलेव्स

@ max630 आप सही हैं। DI को निर्भरता तोड़ने के लिए नहीं कहा जा सकता है। DI, वास्तव में, निर्भरता की शुरुआत करने की एक विधि है , और युग्मन के संबंध में पूछे गए प्रश्न के लिए वास्तव में रूढ़िवादी है। एफ (या इसे घेरने वाले इंटरफ़ेस) में एक परिवर्तन को अभी भी ए और बी दोनों में बदलाव की आवश्यकता होगी
किंग-साइड-स्लाइड

1

मुझे यकीन नहीं है कि आगे के संदर्भ के बिना एक उत्तर समझ में आता है।

क्या Aपहले से ही Bया इसके विपरीत निर्भर करता है ? - किस मामले में हमारे पास घर के लिए एक स्पष्ट विकल्प हो सकता है F

क्या Aऔर Bपहले से ही किसी भी सामान्य निर्भरता को साझा करते हैं जो एक अच्छा घर हो सकता है F?

कितना बड़ा / जटिल है F? और क्या Fनिर्भर करता है?

क्या मॉड्यूल Aऔर Bउसी परियोजना में उपयोग किए जाते हैं?

विल Aऔर Bसाझा करने के लिए कुछ सामान्य निर्भरता वैसे भी खत्म हो?

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

दूसरी ओर यदि आप जावा या सी # डीएलएल के बारे में बात कर रहे हैं जो एकल निष्पादन वातावरण में मूल रूप से संयोजित होते हैं, तो यह एक और मामला है।


एक फ़ंक्शन एक अमूर्त है, और DRY का समर्थन करता है।

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

इसलिए, मैं केवल एक एकल फ़ंक्शन को एक नए मॉड्यूल में स्थानांतरित करने की तुलना में एक बेहतर अमूर्तता बनाने के लिए देखने Aऔर Bइस पर निर्भर होने का तर्क दूंगा C। 

मैं एक नई अमूर्तता में छेड़ने के लिए फ़ंक्शंस के सेट की तलाश में रहूंगा, जो यह कहना है कि मैं तब तक इंतजार कर सकता हूं जब तक कि कोड आधार आगे के साथ-साथ एक पूर्ण / अधिक पूर्ण अमूर्तन की पहचान करने के लिए नहीं, बल्कि एक आधारित के रूप में करने के लिए किसी एकल फ़ंक्शन कोड पर बताएं।


2
क्या यह युगल गर्भपात और निर्भरता ग्राफ के लिए खतरनाक नहीं है?
19ile में बेसिलेव्स

Does A already depend on B or vice versa? — in which case we might have an obvious choice of home for F.यह मानता है कि A हमेशा B (या इसके विपरीत) पर निर्भर करेगा, जो एक बहुत ही खतरनाक धारणा है। तथ्य यह है कि ओपी एफ को स्वाभाविक रूप से ए (या बी) का हिस्सा नहीं देखता है, यह बताता है कि एफ या तो पुस्तकालय के लिए निहित होने के बिना मौजूद है। यदि F एक लाइब्रेरी (उदाहरण के लिए DbContext एक्सटेंशन मेथड (F) और एक एंटिटी फ्रेमवर्क रैपर लाइब्रेरी (A या B)) से संबंधित है, तो OP का प्रश्न मूट होगा।
फ्लेटर

0

यहाँ जवाब है कि आप सभी तरीकों पर ध्यान केंद्रित कर सकते हैं "कम से कम" इस समस्या को आप एक काम कर रहे हैं। और "समाधान" बस युग्मन बनाने के लिए अलग-अलग तरीके की पेशकश करना वास्तव में समाधान नहीं हैं।

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

अपने आप से पूछें कि मॉड्यूल A और B अलग क्यों हैं यदि वे दोनों एक ही फ़ंक्शन F पर निर्भर हैं? यदि आप एक खराब डिजाइन के लिए निश्चित रूप से निर्भरता प्रबंधन / अमूर्त / युग्मन / आप-नाम-के साथ समस्या है।

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

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

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


क्या आप हर एप्लिकेशन में ठीक एक मॉड्यूल रखने का सुझाव देते हैं?
बसिलेव्स

@Basilevs बिल्कुल नहीं (जब तक कि यह वारंटी नहीं है)। मेरा सुझाव है कि संभव के रूप में कई पूरी तरह से डिकोड किए गए मॉड्यूल हैं। सब के बाद, यह एक मॉड्यूल का पूरा उद्देश्य है।
राजा-पक्ष-स्लाइड

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

@Basilevs का तात्पर्य है कि A और B का प्रश्न ठीक से नहीं किया गया है। यह इस अंतर्निहित कमी है जो पहली जगह में समस्या पैदा कर रहा है। निश्चित रूप से साधारण तथ्य यह है कि वे कर अस्तित्व सबूत है कि वे नहीं है चाहिए मौजूद हैं। यही बात मैं ऊपर कर रहा हूं। स्पष्ट रूप से, DRY को तोड़ने से बचने के लिए एक वैकल्पिक डिजाइन आवश्यक है। यह समझना महत्वपूर्ण है कि इन सभी "डिजाइन प्रिंसिपलों" का उद्देश्य एक आवेदन को बदलने के लिए आसान बनाना है।
राजा-पक्ष-स्लाइड

क्या अन्य तरीकों का एक टन था, पूरी तरह से अलग निर्भरता के कारण खराब हो गया और फिर से होना पड़ा, सिर्फ इस कारण एक गैर-आकस्मिक? या क्या आप मानते हैं कि, मॉड्यूल A और B में एक ही विधि है?
बसिलेव्स

0

ये सभी विकल्प मॉड्यूल के बीच अतिरिक्त निर्भरता उत्पन्न करते हैं। वे युग्मन की लागत पर DRY सिद्धांत को लागू करते हैं।

मेरे पास एक अलग राय है, कम से कम तीसरे विकल्प के लिए:

अपने विवरण से:

  • A को F की आवश्यकता है
  • B को F की आवश्यकता है
  • न तो A और न ही B को एक दूसरे की आवश्यकता है।

F को C मॉड्यूल में डालने से युग्मन में वृद्धि नहीं होती है क्योंकि A और B दोनों को पहले से ही C की सुविधा की आवश्यकता होती है।

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