विरासत पर रचना लेकिन


13

मैं खुद को सॉफ्टवेयर इंजीनियरिंग सिखाने की कोशिश कर रहा हूं और कुछ परस्पर विरोधी सूचनाओं के खिलाफ आ रहा हूं, जो मुझे भ्रमित कर रही हैं।

मैं OOP सीख रहा हूं और क्या अमूर्त वर्ग / इंटरफेस हैं और उनका उपयोग कैसे करना है, लेकिन फिर मैं यह पढ़ रहा हूं कि किसी को 'विरासत पर अनुकूल रचना' चाहिए। मैं समझता हूँ कि रचना तब होती है जब एक वर्ग उस नई वस्तु की कार्यक्षमता के साथ उपयोग / बातचीत करने के लिए किसी अन्य वर्ग की वस्तु बनाता / बनाता है।

तो मेरा सवाल है ... क्या मैं अमूर्त वर्गों और इंटरफेस का उपयोग नहीं करना चाहिए? एक अमूर्त वर्ग बनाने के लिए और कंक्रीट कक्षाओं में उस अमूर्त वर्ग की कार्यक्षमता का विस्तार / वारिस करने के लिए, और इसके बजाय, नई वस्तुओं को दूसरे वर्ग की कार्यक्षमता का उपयोग करने के लिए न लिखें?

या, क्या मैं रचना और अमूर्त वर्गों से विरासत का उपयोग करने वाला हूं; एक दूसरे के साथ संयोजन में उन दोनों का उपयोग? यदि हां, तो क्या आप कुछ उदाहरण प्रदान कर सकते हैं कि यह कैसे काम करेगा और इसके लाभ क्या हैं?

चूंकि मैं PHP के साथ सबसे अधिक आरामदायक हूं, इसलिए मैं अन्य भाषाओं पर जाने से पहले अपने OOP / SE कौशल में सुधार करने के लिए इसका उपयोग कर रहा हूं और अपने नए अधिग्रहीत SE कौशल को स्थानांतरित कर रहा हूं, इसलिए PHP का उपयोग करने वाले उदाहरण सबसे अधिक सराहे जाएंगे।


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

2
"फेवर एक्स ओवर वाई" का मतलब यह नहीं है कि कभी भी वाई का उपयोग न करें, बस इस बारे में सोचें कि क्या एक्स बेहतर होगा
रिचर्ड टिंगल

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

1
@MasonWheeler, वंशानुक्रम के लिए कोई मान्य उपयोग-मामले नहीं हैं। यह कम से कम "बुराई" के रूप में एक विशेषता है "गोटो" के रूप में।
डेविड अर्नो

1
@DavidArno यह सिर्फ सादा हास्यास्पद है। प्रोग्रामिंग के पूरे इतिहास में विकसित, सबसे उपयोगी, उत्पादक विशेषताओं में से एक है। उपयोगी कुछ भी होने के साथ, इसका दुरुपयोग करने के बहुत सारे तरीके हैं, लेकिन इसका सही तरीके से उपयोग करने से आपके काम की शक्ति और उत्पादकता बढ़ जाती है।
मेसन व्हीलर

जवाबों:


19

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

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

टेम्पलेट विधि उस मामले का एक अच्छा उदाहरण है जहां विरासत उपयुक्त है।

रचना और वंशानुक्रम के बीच चयन करने के दिशानिर्देशों के लिए यह उत्तर देखें ।


+1 यह इंगित करने के लिए कि किसी वर्ग के आंशिक पुन: उपयोग के मामले में, अप्रयुक्त भाग को विरासत के साथ तुलना में अधिक सफाई से अनदेखा किया जाता है।
लॉरेंस

4

मैं PHP के साथ उस भाषा में आपको ठोस उदाहरण देने के लिए पर्याप्त रूप से परिचित नहीं हूं, लेकिन यहां कुछ दिशानिर्देश दिए गए हैं जो मुझे उपयोगी लगे हैं।

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

उदाहरण के लिए, यदि आप एक JSON एप पर काम कर रहे हैं, तो आप दो तरीकों को निर्दिष्ट करने वाले एक इंटरफ़ेस को परिभाषित कर सकते हैं: "toJson" और "toStatusCode"। यह आपको एक सहायक लिखने की अनुमति देगा जो इस इंटरफ़ेस को लागू करने वाली किसी भी वस्तु को ले सकता है, और इसे Http प्रतिक्रिया में बदल सकता है।

ज्यादातर समय, यह प्रत्यक्ष विरासत के लिए बेहतर है, क्योंकि यह कमजोर आधार वर्ग की समस्या से ग्रस्त होने की संभावना कम है, क्योंकि यह उथले वर्ग पदानुक्रम की ओर जाता है।

डायरेक्ट इनहेरिटेंस के बारे में सबसे अच्छा सोचा जाता है कि आप ऐसा कुछ करते हैं जब ऐसा करने के लिए सम्मोहक कारण होते हैं, बजाय इसके कि आप कुछ ऐसा करें जब तक कि मजबूर करने वाले कारण न हों।

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

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

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

यह, निश्चित रूप से, हमेशा संभव नहीं है। उदाहरण के लिए, प्ले वेब फ्रेमवर्क एक JSON लाइब्रेरी प्रदान करता है जो मूल रूप से एक डोमेन विशिष्ट भाषा है। इसे बदलना एक बड़ा उपक्रम होगा, जिसमें से कॉल को 'Json.prettyPrint' में बदलना केवल एक बहुत ही मामूली हिस्सा होगा।


1

रचना तब होती है जब एक वर्ग (संभवतः आंतरिक) वर्ग को तत्काल क्रिया करके कुछ कार्यक्षमता प्रदान करता है जो पहले से ही उस वर्ग को विरासत में देने के बजाय इस कार्यक्षमता को लागू करता है।

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

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

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

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

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

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

यहाँ रचना बनाम उत्तराधिकार प्रश्न के उत्तर के लिए अंगूठे का नियम है:

क्या मेरी कक्षा में इंटरफ़ेस का "संबंध" है जिसे उसे उजागर करने की आवश्यकता है? यदि हाँ, तो विरासत का उपयोग करें। यदि नहीं, तो रचना का उपयोग करें।

एक जहाज "एक फ्लोटिंग मशीन, और एक फ्लोटिंग मशीन" एक "मशीन" है। तो, विरासत उन लोगों के लिए पूरी तरह से ठीक है। लेकिन एक जहाज, निश्चित रूप से, एक हेलीपैड नहीं है। इसलिए यह हेलिपैड की कार्यक्षमता को बेहतर ढंग से रचता है।

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