ऑब्जेक्ट ओरिएंटेड डिज़ाइन में ढीली युग्मन


16

मैं GRASP सीखने की कोशिश कर रहा हूँ और मैंने पाया कि यह ( पेज 3 पर ) लो कपलिंग के बारे में बताया गया है और जब मैंने पाया तो मुझे बहुत आश्चर्य हुआ:

addTrackएक Albumकक्षा के लिए विधि पर विचार करें , दो संभावित विधियाँ हैं:

addTrack( Track t )

तथा

addTrack( int no, String title, double duration )

कौन सी विधि युग्मन को कम करती है? दूसरा एक करता है, क्योंकि एल्बम वर्ग का उपयोग करने वाले वर्ग को ट्रैक क्लास जानने की आवश्यकता नहीं है। सामान्य तौर पर, विधियों के मापदंडों को आधार प्रकार (int, char ...) और कक्षाओं को जावा से उपयोग करना चाहिए। * संकुल।

मैं इस के साथ diasgree करते हैं; मेरा मानना addTrack(Track t)है कि addTrack(int no, String title, double duration)विभिन्न कारणों से बेहतर है :

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

  2. यदि addTrackएक इंटरफ़ेस का एक तरीका है, और आवश्यकताओं की आवश्यकता है कि Trackअधिक जानकारी होनी चाहिए (वर्ष या शैली) तो इंटरफ़ेस को बदलना होगा और इसलिए कि विधि को किसी अन्य पैरामीटर का समर्थन करना चाहिए।

  3. एनकैप्सुलेशन टूट गया है; यदि addTrackएक इंटरफेस में है, तो यह के आंतरिक पता नहीं होना चाहिए Track

  4. यह वास्तव में कई मापदंडों के साथ दूसरे तरीके से अधिक युग्मित है। मान लीजिए noपैरामीटर जरूरतों से परिवर्तित करने की intकरने के लिए long, क्योंकि वहाँ की तुलना में अधिक कर रहे हैं MAX_INTपटरियों (या जो भी कारण के लिए); तब Trackऔर विधि दोनों को बदलने की जरूरत है, जबकि अगर विधि addTrack(Track track)केवल Trackहोगी-तो बदल दी जाएगी।

सभी 4 तर्क वास्तव में एक दूसरे के साथ जुड़े हुए हैं, और उनमें से कुछ अन्य से परिणाम हैं।

कौन सा दृष्टिकोण बेहतर है?


2
क्या यह एक दस्तावेज है जो एक प्रोफेसर या ट्रेनर द्वारा एक साथ रखा गया था? आपके द्वारा प्रदान किए गए लिंक के URL के आधार पर, ऐसा लगता है कि यह एक वर्ग के लिए था, हालांकि मुझे दस्तावेज़ में कोई क्रेडिट नहीं दिखता है कि इसे किसने बनाया है। यदि यह एक कक्षा का हिस्सा होता, तो मैं आपको सुझाव देता हूं कि आप दस्तावेज़ प्रदान करने वाले व्यक्ति के इन प्रश्नों को पूछें। मैं आपके तर्क से सहमत हूँ, वैसे - यह मुझे स्पष्ट प्रतीत होगा कि एक एल्बम वर्ग स्वाभाविक रूप से एक ट्रैक वर्ग के बारे में जानना चाहेगा।
डेरेक

ईमानदारी से, जब भी मैं "बेस्ट प्रैक्टिस" के बारे में पढ़ता हूं, तो मैं उन्हें नमक के दाने के साथ लेता हूं!
आरा

@ डेरेक ने "ग्रैस पैटर्न उदाहरण" के लिए Google खोजकर दस्तावेज़ पाया; मैं नहीं जानता कि यह किसने लिखा है, लेकिन चूंकि यह एक विश्वविद्यालय से था, मेरा मानना ​​है कि यह विश्वसनीय है। मैं दी गई जानकारी और स्रोत की अनदेखी के आधार पर एक उदाहरण की तलाश कर रहा हूं।
m3th0dman

4
@ m3th0dman "लेकिन चूंकि यह एक विश्वविद्यालय से था, मेरा मानना ​​है कि यह विश्वसनीय है।" मेरे लिए क्योंकि यह एक विश्वविद्यालय से है, मैं इसे अविश्वसनीय मानता हूं। मैं किसी ऐसे व्यक्ति पर भरोसा नहीं करता, जिसने सॉफ्टवेयर विकास में सर्वोत्तम प्रथाओं के बारे में बात करते हुए मल्टीयर प्रोजेक्ट्स पर काम नहीं किया है।
आरा

1
@AraK विश्वसनीय का मतलब निर्विवाद नहीं है; और यही मैं यहां कर रहा हूं, इस पर सवाल करना।
m3th0dman 16

जवाबों:


15

खैर, आपके पहले तीन बिंदु वास्तव में युग्मन के अलावा अन्य सिद्धांतों के बारे में हैं। आपको हमेशा int-परस्पर विरोधी डिजाइन सिद्धांतों के बीच संतुलन बनाना पड़ता है।

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

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

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

अब केवल स्थानीय के बजाय नेटवर्क पर पटरियों को चलाने के लिए समर्थन जोड़ने की आवश्यकता पर विचार करें। आपको बस एक ऐसी NetworkTrackवस्तु बनाने की ज़रूरत है जो समान इंटरफ़ेस के अनुरूप हो। Trackवस्तु के बिना , आपको हर जगह फ़ंक्शंस बनाने होंगे:

addNetworkTrack(int no, string title, double duration, URL location)

यह प्रभावी रूप से आपके युग्मन को दोगुना करता है, यहां तक ​​कि उन मॉड्यूलों की भी आवश्यकता होती है जो नेटवर्क-विशिष्ट सामान की परवाह नहीं करते हैं फिर भी इसे ट्रैक करने के लिए, इसे पारित करने में सक्षम होने के लिए।

युग्मन की सही मात्रा निर्धारित करने के लिए आपका रिपल इफेक्ट टेस्ट एक अच्छा है। हम जिन चीज़ों से चिंतित हैं, उन जगहों को सीमित कर रहे हैं जो बदलाव को प्रभावित करता है।


1
+ प्राथमिकताओं को युग्मित करना अभी भी युग्मन है चाहे वह कटा हुआ क्यों न हो।

एक URL विकल्प / लहर प्रभाव जोड़ने के लिए +1।
user949300

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

कुल प्रणाली युग्मन और मॉड्यूल युग्मन के बीच के अंतर के बारे में अच्छे से समझाने के कारण स्वीकृत उत्तर।
m3th0dman

10

मेरी सिफारिश है:

उपयोग

addTrack( ITrack t )

लेकिन यकीन है कि ITrackएक इंटरफ़ेस है और एक ठोस वर्ग नहीं है।

एल्बम ITrackकार्यान्वयनकर्ताओं के इंटर्नल को नहीं जानता है । यह केवल अनुबंध द्वारा परिभाषित किया गया है ITrack

मुझे लगता है कि यह समाधान है जो युग्मन की कम से कम मात्रा उत्पन्न करता है।


1
मेरा मानना ​​है कि ट्रैक केवल एक साधारण बीन / डेटा ट्रांसफर ऑब्जेक्ट है, जहां यह केवल फ़ील्ड्स और उन पर गेटर्स / सेटर हैं; क्या इस मामले में एक इंटरफ़ेस आवश्यक है?
m3th0dman

6
आवश्यक है? शायद ऩही। सुझाव दिया, हाँ। एक ट्रैक का ठोस अर्थ और विकसित हो सकता है, लेकिन उपभोग करने वाले वर्ग को इससे क्या चाहिए, शायद नहीं।
जस्टिन सी सी

2
@ m3th0dman हमेशा सार पर निर्भर करते हैं, न कि सहमति पर। यह Trackगूंगा या स्मार्ट होने की परवाह किए बिना लागू होता है । Trackएक सहमति है। ITrackइंटरफ़ेस एक अमूर्तता है। इस तरह से आपको भविष्य में विभिन्न प्रकार के ट्रैक्स का पालन करना होगा, जब तक वे इसका अनुपालन करते हैं ITrack
ट्यूलेंस कोर्डोवा

4
मैं विचार से सहमत हूं, लेकिन 'मैं' उपसर्ग खो देता हूं। रॉबर्ट मार्टिन द्वारा क्लीन कोड से, पृष्ठ 24: "पूर्ववर्ती I, आज ​​की विरासत वार्डों में इतनी आम, सबसे अच्छी और बहुत अधिक जानकारी में एक व्याकुलता है। मैं अपने उपयोगकर्ताओं को यह जानना नहीं चाहता कि मैं उन्हें सौंप रहा हूं। इंटरफेस।"
बेंजामिन ब्रुमफील्ड

1
@BenjaminBrumfield आप सही हैं। मुझे उपसर्ग पसंद नहीं है, हालांकि मैं स्पष्टता के जवाब में छोड़ दूंगा।
ट्यूलेंस कोर्डोवा

4

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

पहला उदाहरण विधि मानती है कि एल्बम वर्ग के बाहर एक ट्रैक तुरंत हो रहा है, इसलिए बहुत कम से कम, हम मान सकते हैं कि ट्रैक वर्ग का तात्कालिकता एल्बम वर्ग के लिए युग्मित नहीं है।

यदि सर्वोत्तम प्रथाओं ने सुझाव दिया कि हमारे पास कभी भी एक वर्ग का संदर्भ नहीं है तो दूसरा वर्ग, ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग की संपूर्णता को खिड़की से बाहर फेंक दिया जाएगा।


मैं यह नहीं देखता कि किसी अन्य वर्ग के लिए एक अंतर्निहित संदर्भ होने से यह स्पष्ट संदर्भ होने की तुलना में अधिक युग्मित हो जाता है। किसी भी तरह से, दो वर्गों युग्मित हैं। मुझे लगता है कि युग्मन स्पष्ट होना बेहतर है, लेकिन मुझे नहीं लगता कि यह किसी भी तरह से "अधिक" युग्मित है।
TMN

1
@TMN, अतिरिक्त युग्मन इस बात में है कि मैं कैसे कहता हूं कि दूसरा उदाहरण संभवत: आंतरिक रूप से एक नया ट्रैक ऑब्जेक्ट बनाएगा। ऑब्जेक्ट की तात्कालिकता को एक ऐसी विधि के साथ जोड़ा जा रहा है, जो अन्यथा एल्बम ऑब्जेक्ट में किसी प्रकार की सूची में ट्रैक ऑब्जेक्ट को जोड़ना चाहिए (एकल जिम्मेदारी सिद्धांत को तोड़ते हुए)। जिस तरह से ट्रैक को बनाया जाता है, उसे कभी भी बदलने की आवश्यकता होती है, ऐडट्रैक () विधि को भी बदलना होगा। पहले उदाहरण के मामले में ऐसा नहीं है।
डेरेक

3

युग्मन आपके कोड में प्राप्त करने के लिए कई पहलुओं में से एक है। युग्मन को कम करके, आप आवश्यक रूप से अपने कार्यक्रम में सुधार नहीं कर रहे हैं। सामान्य तौर पर, यह एक सर्वोत्तम अभ्यास है, लेकिन इस विशेष उदाहरण में, क्यों नहीं Trackजाना चाहिए ?

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

आप उल्लेख करते हैं कि एनकैप्सुलेशन टूट गया है, लेकिन यह नहीं है। Albumइन्टर्ल्स के बारे में पता होना चाहिए Track, और यदि आपने किसी ऑब्जेक्ट का उपयोग नहीं किया है, Albumतो इससे पहले कि यह सभी का उपयोग कर सकता है , प्रत्येक जानकारी को उसके पास से गुजरना होगा। कॉल करने वाले को आंतरिक Trackरूप से अच्छी तरह से पता होना चाहिए , क्योंकि उसे एक Trackऑब्जेक्ट का निर्माण करना होगा , लेकिन कॉल करने वाले को यह जानकारी सभी को समान रूप से पता होनी चाहिए यदि इसे सीधे विधि में पारित किया गया था। दूसरे शब्दों में, यदि एनकैप्सुलेशन का लाभ किसी वस्तु की सामग्री को नहीं जान रहा है, तो संभवतः इसे इस मामले में उपयोग नहीं किया जा सकता है क्योंकि Albumइसे Trackकेवल एक ही जानकारी का उपयोग करना चाहिए ।

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

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

बेशक, यह सिर्फ एक उदाहरण है। मुझे यकीन है कि यह आपका मामला नहीं है, और इसलिए Trackअपराध-मुक्त का उपयोग करने के लिए स्वतंत्र महसूस करें। जब आप कक्षाओं का निर्माण कर रहे हों और जब आवश्यकता हो तो इंटरफेस बनाने के लिए बस अपने कॉलर को ध्यान में रखें।


3

दोनों सही हैं

addTrack( Track t ) 

है बेहतर (आप पहले से ही argumented के रूप में) है, जबकि

addTrack( int no, String title, double duration ) 

है कम मिलकर क्योंकि कोड है कि का उपयोग करता है addTrackपता करने के लिए एक है कि वहाँ की जरूरत नहीं है Trackवर्ग। कॉलिंग कोड को अपडेट करने की आवश्यकता के बिना ट्रैक का नाम बदला जा सकता है।

जब आप अधिक पठनीय / बनाए रखने योग्य कोड के बारे में बात कर रहे हैं, तो लेख युग्मन के बारे में बात कर रहा है । कम युग्मित कोड को लागू करना और समझना आसान नहीं है।


तर्क 4 देखें; मैं यह नहीं देखता कि दूसरा एक कम युग्मित कैसे है।
m3th0dman

3

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

इसके बजाय, उचित एवेन्यू ठोस वस्तुओं पर निर्भरता को कम करना है , जो कि "ढीली युग्मन" का सिद्धांत है। कम निश्चित ठोस प्रकार एक विधि का ज्ञान होना बेहतर है। उस कथन के अनुसार, पहला विकल्प वास्तव में कम युग्मित है, क्योंकि सरल प्रकार लेने वाली दूसरी विधि को उन सभी सरल प्रकारों के बारे में जानना चाहिए। सुनिश्चित करें कि वे बिल्ट-इन हैं, और विधि के अंदर कोड की देखभाल करनी पड़ सकती है, लेकिन विधि के हस्ताक्षर और विधि के कॉलर्स निश्चित रूप से नहीं । वैचारिक ऑडियो ट्रैक से संबंधित इन मापदंडों में से एक को बदलने पर ट्रैक ऑब्जेक्ट (जो ऑब्जेक्ट्स का बिंदु; एनकैप्सुलेशन) में निहित होने पर अलग-अलग बनाम अधिक परिवर्तन की आवश्यकता होती है।

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

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

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