क्यों उपवर्ग बहुत अधिक खराब है (और इसलिए हमें इसके साथ दूर करने के लिए प्रोटोटाइप का उपयोग क्यों करना चाहिए)?


10

मैं डिजाइन पैटर्न पर पढ़ रहा था, और मैंने पढ़ा कि प्रोटोटाइप डिजाइन पैटर्न अत्यधिक उपवर्ग के साथ दूर करता है।

उपवर्ग खराब क्यों है? एक प्रोटोटाइप का उपयोग करने से उप-वर्ग में क्या फायदा होगा?


कौन कहता है ? क्या आपके पास एक लिंक है ?
कैमस

मैं इस पुस्तक का p.118 पढ़ रहा था। goo.gl/6JGw1
डेविड फॉक्स

जवाबों:


19

क्यों उपवर्ग बहुत ज्यादा खराब है

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

प्रोटोटाइप पैटर्न उपवर्ग के साथ दूर करता है

या सवाल का अर्थ है "बहुत अधिक उपवर्ग के साथ दूर करता है?"। यह पैटर्न सबक्लासिंग से बचने के लिए "टेम्पलेट" ऑब्जेक्ट को क्लोन करने के लिए कहता है, कम से कम उस बिंदु पर। ऐसा कोई नियम नहीं है जो कहता है कि "टेम्पलेट" एक उपवर्ग नहीं हो सकता है।

वंशानुक्रम पर अनुकूल रचना

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

जब एक वर्ग भागों से बना होता है तो आप उन भागों को रनटाइम में स्थानापन्न कर सकते हैं । यह परीक्षण क्षमता पर गहरा प्रभाव डालता है।

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

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


मैं वास्तव में कुछ उदाहरणों को देखने के लिए इच्छुक हूँ, जब वंशानुक्रम परीक्षण (विशेष रूप से मज़ाक करना) कठिन बनाता है और रचना किस तरह से मदद करती है।
आर्मंड

@alison: एक व्युत्पन्न वर्ग में एक विधि जो बेस क्लास से दूसरी विधि का उपयोग करती है जहां बेस क्लास में कार्यान्वयन त्रुटि परिदृश्यों का परीक्षण करना लगभग असंभव बना देता है। अगर वह रचना होती तो किसी वस्तु को इंजेक्ट करना आसान होता जो कि त्रुटि पैदा करती है
Rune FS

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

8

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

मैं खुद इस बारे में अज्ञेय हूं। यह कहना बुरा लगता है कि यह केवल बुरा है। दुरुपयोग होने पर कुछ भी बुरा है।


2

दो कारण।

  1. रनटाइम प्रदर्शन है। हर बार जब आप एक सुपरक्लास से एक उपवर्ग का आह्वान करते हैं, तो आप एक विधि कॉल कर रहे हैं, यदि आपने पांच वर्गों को नेस्ट किया है और बेस क्लास में एक विधि का आह्वान करते हैं, तो आप पांच विधि चालान करेंगे। अधिकांश कंपाइलर / रनटाइम्स इसे पहचानने और अतिरिक्त कॉल को दूर करने की कोशिश करेंगे, लेकिन केवल बहुत ही सरल मामलों के लिए ऐसा करना सुरक्षित है।

  2. अपने साथी प्रोग्रामरों की पवित्रता है। यदि आप पांच कक्षाओं को घोंसला बनाते हैं, तो मुझे स्थापित करने के लिए सभी चार मूल वर्गों की जांच करनी होगी कि आप वास्तव में बेस क्लास में एक विधि कह रहे हैं, यह थकाऊ है। जब मैं प्रोग्राम डीबग करता हूं, तो मुझे पांच विधि इनवॉइस के माध्यम से भी कदम उठाना पड़ सकता है।


6
-1: आप # 2 के बारे में सही हैं; लेकिन # 1 के बारे में नहीं। वंशानुक्रम की कई परतें अनिवार्य रूप से रनटाइम प्रदर्शन को प्रभावित नहीं करेंगी ।
जिम जी।

मशीन कोड स्तर पर अतिरिक्त प्रक्रिया कॉल की एक जोड़ी के बारे में चिंतित और ओपी और वंशानुक्रम का उपयोग करते हुए, और आप अपने साथी प्रोग्रामर की पवित्रता के बारे में चिंता करते हैं .....
Mattnz

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

2

"बहुत ज्यादा" एक निर्णय कॉल है।

प्रोग्रामिंग में अधिकांश चीजों के साथ, उप-वर्गीकरण स्वाभाविक रूप से बुरा नहीं है जब यह समझ में आता है। जब आपकी समस्या समाधान का मॉडल भागों की रचना के बजाय पदानुक्रम के रूप में अधिक समझ में आता है, तो उप-वर्ग पसंदीदा विकल्प हो सकता है।

उन्होंने कहा, वंशानुक्रम पर अनुकूल रचना अंगूठे का एक अच्छा नियम है।

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

उपवर्ग आपको अपने कार्यान्वयन के विवरणों को उजागर करने का कारण भी बन सकता है जो आप नहीं करना चाहते हैं। इससे आपके डेटा के अंतर्निहित प्रतिनिधित्व तक पहुंच को नियंत्रित करना मुश्किल हो जाता है और यह आपको अपने बैकिंग मॉडल के एक विशेष कार्यान्वयन के लिए बाध्य करता है।

एक उदाहरण मैं सोच सकता हूं कि java.util.Properties है, जो हैशटेबल से विरासत में मिली है। गुण वर्ग केवल स्ट्रिंग-स्ट्रिंग जोड़े (यह Javadocs में नोट किया गया है) को संग्रहीत करने का इरादा है। वंशानुक्रम के कारण, हैशटेबल से पुट और पुट विधियां गुणों के उपयोगकर्ताओं के सामने आ गई हैं। जबकि एक संपत्ति को स्टोर करने का "सही" तरीका सेटप्रॉपर्टी () के साथ है, वहाँ एक उपयोगकर्ता को पुट () और स्ट्रिंग और ऑब्जेक्ट में पास होने से रोकने के लिए कुछ भी नहीं है।

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


2

वंशानुक्रम कुछ मामलों में अतिक्रमण को तोड़ सकता है , और यदि ऐसा होता है तो यह बुरा है। अधिक के लिए पढ़ें।


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

जैसा कि जरूरतें विकसित होती हैं, पुस्तकालय विकसित हो सकता है और अधिक ग्राहक हो सकते हैं; या यह अन्य स्वादों के साथ अपने स्वयं के वर्ग से विरासत में विस्तारित कार्यक्षमता प्रदान कर सकता है। अब तक सब ठीक है।

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

संक्षेप में, जबकि यह हमेशा मामला नहीं हो सकता है, लेकिन,

इनकैप्सुलेशन को तोड़ने के लिए विरासत का दुरुपयोग करना आसान है

यदि उस बिंदु पर उप-वर्ग की अनुमति देना गलत हो सकता है।


1

लघु त्वरित उत्तर:

यह इस बात पर निर्भर करता है कि आप क्या कर रहे हैं।

विस्तारित बोरिंग उत्तर:

एक डेवलपर एक ऐप बना सकता है। या तो, उपवर्ग या (प्रोटोटाइप) टेम्प्लेट का उपयोग करना। कभी-कभी एक तकनीक बेहतर काम करती है। कभी-कभी अन्य टेचिंक बेहतर काम करता है।

तकनीक के साथ चुनना सबसे अच्छा काम करता है, यह भी विचार करने की आवश्यकता होती है कि क्या "मल्टीपल इनहेरिटेंस" परिदृश्य इसके वर्तमान है। भले ही प्रोग्रामिंग भाषा केवल एकल वंशानुक्रम, टेम्पलेट या प्रोटोटाइप का समर्थन करती हो।

पूरक नोट:

कुछ उत्तर "एकाधिक वंशानुक्रम" से संबंधित हैं। मुख्य प्रश्न नहीं, यह विषय से संबंधित है। "एकाधिक वंशानुक्रम बनाम रचना" के बारे में कई, समान, पोस्ट हैं। मेरे पास एक मामला था जहां मैं दोनों को मिलाता हूं।

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