आधार फ़ील्ड में एक सामान्य फ़ील्ड को कब स्थानांतरित करना है?


16

मेरे पास वर्तमान में दो व्युत्पन्न वर्ग हैं, Aऔर B, कि दोनों में एक क्षेत्र सामान्य है और मैं यह निर्धारित करने की कोशिश कर रहा हूं कि क्या इसे आधार वर्ग में जाना चाहिए।

इसे बेस क्लास से संदर्भित नहीं किया जाता है, और कहते हैं कि अगर सड़क के नीचे कुछ बिंदु पर एक और वर्ग व्युत्पन्न होता है C, जिसमें ए नहीं है _field1, तो "कम से कम विशेषाधिकार प्राप्त" (या कुछ) के प्रिंसिपल का उल्लंघन नहीं होगा यदि यह था?

public abstract class Base
{
    // Should _field1 be brought up to Base?
    //protected int Field1 { get; set; }
}

public class A : Base
{
    private int _field1;
}

public class B : Base
{
    private int _field1;
}

public class C : Base
{
    // Doesn't have/reference _field1
}

18
मुझे लगता है कि इस सवाल का स्पष्ट नहीं है क्योंकि आप हमें क्या की किसी भी विचार नहीं दिया है Base, A, B, C, और _field1कर रहे हैं। वे महत्वपूर्ण विवरण हैं जिन्हें नहीं छोड़ा जाना चाहिए; मुझे लगता है कि आपको उन लोगों के बारे में बात करने के लिए प्रश्न को संपादित करना चाहिए।
टान्नर स्विट

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

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

शुरुआत करने के लिए आपके पास बेस क्लास क्यों है?
jpmc26

जवाबों:


34

यह सब उस सटीक समस्या पर निर्भर करता है जिसे आप हल करने की कोशिश कर रहे हैं।

एक ठोस उदाहरण पर विचार करें: आपका सार आधार वर्ग है Vehicleऔर आपके पास वर्तमान में ठोस कार्यान्वयन Bicycleऔर हैं Car। आप वाहन numberOfWheelsसे Bicycleऔर जाने पर विचार कर रहे हैं Car। क्या आपको ऐसा करना चाहिए? नहीं! क्योंकि सभी वाहनों में पहिए नहीं होते हैं। आप पहले से ही बता सकते हैं कि यदि आप एक Boatवर्ग जोड़ने की कोशिश करते हैं तो यह टूटने वाला है।

अब, यदि आपका सार आधार वर्ग था, WheeledVehicleतो numberOfWheelsवहाँ सदस्य चर होना तर्कसंगत है ।

आपको अपनी समस्या पर एक ही तर्क लागू करने की आवश्यकता है, क्योंकि जैसा कि आप देख सकते हैं, यह एक साधारण हां या कोई जवाब नहीं है।


3
कोई अस्थायी रूप से स्वीकार कर सकता है कि 0 एक वैध संख्या है। हालाँकि, अंत में आप एक roll()विधि जोड़ सकते हैं , जिस बिंदु पर उपवर्ग विचार प्रस्तुतकर्ता लग रहा है।
user949300

11
एक नाव में 0 पहिए होते हैं। वह क्या टूटता है?
डी ड्रमर

14
@Drmmr यह ऐसा नहीं है कि एक नाव में 0 पहिए होते हैं, यह पहिए नाव की अवधारणा के रूप में भी मौजूद नहीं है - इसलिए आपके मॉडलों को इसके लिए अनुमति नहीं देनी चाहिए।
पीटर एम

10
मेरा कहना है कि उदाहरण खराब है। एक वाहन के साथ वैचारिक रूप से कुछ भी गलत नहीं है (यह नाव होता है) जिसमें कहा गया है कि इसमें 0 पहिए हैं।
D ड्रमर

10
फिर यह सब नरक में जाता है जब आपको पैडल बोट को स्टोर करने की आवश्यकता होती है।
इल्युसिवब्रियन

13

तार्किक रूप से, आधार वर्ग में समान रूप से उपवर्गों में दोहराए गए क्षेत्र को रखने से परे, एक तीसरा विकल्प है: जो पदानुक्रम में एक नया उपवर्ग शुरू करना है जिसमें दोनों के बीच सामान्य गुण हैं। पूरी तरह से वहाँ जाने के बिना @Pete संकेत देता है।

@ पीट के उदाहरण का उपयोग करते हुए, हम पहिएदार वाहन के लिए एक (संभवतः सार) उपवर्ग का परिचय देंगे जो मूल आधार वर्ग से उतरता है - जबकि दो उपवर्ग इससे नीचे उतरते हैं। इस प्रकार, मूल आधार वर्ग पहियों के साथ प्रदूषित नहीं है, फिर भी पहियों की समानता DRY है (पहियों वाले उपवर्गों के बीच दोहराया नहीं जाता है)।

यह निश्चित रूप से, आपके उद्देश्यों के लिए ओवरकिल हो सकता है, लेकिन इस तरह के वर्ग पदानुक्रम तंत्र द्वारा समर्थित है।


यह वास्तव में है जो मैंने करने का फैसला किया है (ए और बी ज्यादातर ओवरलैप करते हैं, इसलिए बी ए से प्राप्त होगा)।
समीस

9

मैं यहाँ शैतान के वकील का किरदार निभाने जा रहा हूँ।

अभी आपको कुछ नहीं करना चाहिए ।

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

इस तरह का निर्णय लेते समय मैं "3 का नियम" का उपयोग करता हूं: एक बार जब मैंने एक ही चीज को दोहराया है जैसे कि तीन अलग-अलग स्थानों पर, और उसके बाद ही, मैं इसे श्रृंखला को आगे बढ़ाने पर विचार करता हूं। एनबी आप केवल 2 पर हैं।


2
निर्णय लेने के लिए आवश्यक एक बुद्धिमान अवलोकन है, मैं कहूंगा।
राडारबॉब

1
मैं ज्यादातर सहमत हूं, लेकिन "अभी" (कोई अतिरिक्त कोड नहीं है जैसा कि हम देखते हैं) दोनों दिशाओं में रिफलेक्टिंग तुच्छ है। लेकिन अगर अतिरिक्त कोड है जो क्षेत्र का उपयोग करता है, तो दोनों दिशाओं में रिफैक्टिंग करना काफी कठिन हो सकता है।
डॉक्टर ब्राउन

2

सामान्य तौर पर, मैं इसे बेस क्लास में ले जाऊंगा। मुझे नहीं लगता कि कोई उद्देश्य हां / नहीं है, क्योंकि यहां एक व्यापार बंद है - अप्रयुक्त क्षेत्रों को ले जाना बनाम जटिलता को कम करना।

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

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


मेरा उदाहरण तुच्छ है, हालांकि यह अभी भी उत्पादन कोड है। आप एक "भारी" आधार वर्ग के साथ पदानुक्रम को "समझौता" करने के लिए एक अच्छा तर्क देते हैं, जिसे मैं भी इस तरह के मामले में खुद को झुकता हुआ देखूंगा।
samis

1
@ एसिस: आप "ए, बी, सी" और "बेस" नामक कक्षाओं का उपयोग केवल एक क्षेत्र के साथ करते हैं और उत्पादन कोड में कोई विधि नहीं है? मैं सवाल करता हूं कि
Doc Brown
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.