2010-11-23 10 views
29

मैंने "मॉडल मॉडल में विरासत डेवलपर जीवन को जटिल बना रहा है" के संबंध में काम पर चर्चा की थी। मैं एक ओओ प्रोग्रामर हूं इसलिए मैंने तर्कों की तलाश शुरू कर दी कि डोमेन मॉडल में विरासत रखने से वास्तव में डेवलपर जीवन को आसानी से जगह पर स्विच करने की बजाय आसानी होगी।डोमेन मॉडल में विरासत बनाम enum गुण

class Animal { 

} 

class Cat : Animal { 

} 

class Dog : Animal { 

} 

क्या अन्य सहयोगी कह रहे हैं:

public enum AnimalType { 
    Unknown, 
    Cat, 
    Dog 
} 

public class Animal { 

    public AnimalType Type { get; set; } 

} 

मैं उसे कैसे समझा दिया है (लिंक स्वागत कर रहे हैं) एक वर्ग है कि

क्या मैं देखना चाहेंगे यह है पदानुक्रम इस तरह की स्थितियों के लिए एक enum संपत्ति होने से बेहतर होगा?

धन्यवाद!

+3

क्या यह इन-मेमोरी ऑब्जेक्ट मॉडल या ओआरएम के लिए है? मुझे पशु उदाहरण बहुत उपयोगी नहीं लगता है क्योंकि यह वास्तविक ओओ डिज़ाइन करते समय आपके सामने आने वाले कई सामान्य मुद्दों का उपयोग नहीं करता है। –

+0

@ मार्सेलो: सहमत हुए। विशेष रूप से, व्यवहार कोण क्या है? – sfinnie

+0

कुत्तों की छाल, बिल्लियों मेयो, आपके सहयोगी के कार्यान्वयन का उपयोग करके, इन व्यवहारों को सी # (उदाहरण के लिए) में लागू करना मुश्किल होगा। यह अभी भी कार्यात्मक भाषाओं में उपयोगी है जैसे एफ # जहां भेदभाव वाले संघ बहुलवाद प्रदान करने के लिए एक बहुत शक्तिशाली साधन हैं। –

उत्तर

24

यहाँ कैसे इसके बारे में मैं कारण नहीं है। उदा।

जैसी चीजों के लिए वंशानुक्रम का उपयोग:

फायरमैन < - कर्मचारी < - व्यक्ति गलत है।

जैसे ही फ्रेडी फायरमैन नौकरी बदलता है या बेरोजगार हो जाता है, आपको उसे मारना होगा और नए प्रकार के नए ऑब्जेक्ट को इसके साथ जुड़े पुराने संबंधों के साथ फिर से बनाना होगा।

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

व्यक्ति वर्ग को भूमिकाओं की एक सूची देने का अधिक सही तरीका होगा। प्रत्येक भूमिका एक समय अवधि के साथ एक रोजगार का प्रतिनिधित्व करता है।

उदा।

freddy.Roles.Add(new Employement(employmentDate, jobTitle)); 

या कि अगर overkill है:

freddy.CurrentEmployment = new Employement(employmentDate, jobTitle); 

इस तरह, फ्रेडी एक डेवलपर w/ओ हम उसे पहले मारने के लिए होने बन सकता है।

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

मेम ओओ में शुद्ध में मैं कहूंगा कि यहां नौकरी के लिए विरासत का उपयोग करना अधिक सही है।

लेकिन यदि आप ओ/आर मैपिंग कर रहे हैं तो आप दृश्यों के पीछे थोड़ा अधिक अपूर्ण डेटा मॉडल के साथ समाप्त हो सकते हैं यदि मैपर प्रत्येक उप प्रकार को एक नई तालिका में मैप करने का प्रयास करता है। तो ऐसे मामलों में, यदि मैं प्रकारों से जुड़े कोई वास्तविक/जटिल व्यवहार नहीं करता हूं तो मैं अक्सर enum दृष्टिकोण के लिए जाता हूं। मैं "अगर टाइप == जॉबटाइटल्स.फिरमैन ..." के साथ रह सकता हूं, यदि उपयोग सीमित है और यह चीजों को आसान या कम जटिल बनाता है।

उदा। .NET के लिए इकाई फ्रेमवर्क 4 डिजाइनर केवल प्रत्येक उप प्रकार को एक नई तालिका में मैप कर सकता है। और जब आप अपने डेटाबेस w/o किसी भी वास्तविक लाभ से पूछते हैं तो आपको एक बदसूरत मॉडल या बहुत सारे मिल सकते हैं।

हालांकि यदि प्रकार/भूमिका स्थिर है तो मैं विरासत का उपयोग करता हूं। उदा। उत्पादों के लिए।

आपके पास सीडी < - उत्पाद और पुस्तक < - उत्पाद हो सकता है। विरासत यहां जीतती है क्योंकि इस मामले में आपके पास इस प्रकार से जुड़े विभिन्न राज्य होते हैं। सीडी में कई ट्रैक संपत्ति हो सकती है जबकि किसी पुस्तक में पृष्ठ की संपत्ति की संख्या हो सकती है।

तो संक्षेप में, यह ;-)

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

अगर Response.Redicted ((उत्पाद बुक है)? "~/EditBook.aspx आईडी" + product.id);

क्योंकि इकाई कक्षा में संपादित पुस्तक यूआरएल एन्कोडिंग सादा बदसूरत होगा, क्योंकि यह अपनी साइट संरचना आदि

+0

हम ईएफ 4 में "टेबल-प्रति-पदानुक्रम विरासत" (http://msdn.microsoft.com/en-us/library/bb738443.aspx) प्राप्त करने में कामयाब रहे ताकि प्रश्न इतने बदसूरत न हों। –

+0

हां तालिका प्रति पदानुक्रम डेटाबेस को थोड़ा और अधिक धीमा कर देता है, हालांकि, इसे काम करने के लिए आपको कितना एक्सएमएल लिखना है? यह _might_ स्विचस्टेटमेंट से अधिक है, बस कह रहा है। –

+0

हमने पहले डेटाबेस के साथ एक्सएमएल लिखना और शेष मैप किए गए इकाइयों को हाथ से बनाने और उन्हें wright table में मैप करने से बचाया। –

1

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

केवल विरासत का उपयोग करता है, तो भूमिका/प्रकार कभी नहीं बदलेगा:

6

Enums अच्छे हैं जब के बारे में पता करने के लिए अपने व्यापार entites मजबूर होना पड़ा:

  1. सेट मूल्यों का निर्धारण किया गया है और कभी भी बहुत ही कम परिवर्तन नहीं होता है।
  2. आप मूल्यों के संघ (यानी झंडे का संयोजन) का प्रतिनिधित्व करने में सक्षम होना चाहते हैं।
  3. आपको प्रत्येक मूल्य को अन्य राज्य से जोड़ने की आवश्यकता नहीं है। (जावा में यह सीमा नहीं है।)

यदि आप किसी समस्या के साथ अपनी समस्या का समाधान कर सकते हैं, तो एक enum संभवतः एक अच्छा फिट और अधिक प्रकार सुरक्षित है। यदि आपको उपर्युक्त की तुलना में अधिक लचीलापन की आवश्यकता है, तो enms संभावित सही उत्तर नहीं है। पॉलिमॉर्फिक कक्षाओं का उपयोग करके, आप कर सकते हैं:

  1. सांख्यिकीय रूप से सुनिश्चित करें कि सभी प्रकार-विशिष्ट व्यवहार को संभाला जाता है। उदाहरण के लिए, यदि आपको Bark() में सक्षम होने के लिए सभी जानवरों की आवश्यकता है, तो Animal कक्षाओं को एक सार Bark() विधि के साथ बनाने से संकलक आपको यह जांचने देगा कि प्रत्येक सबक्लास इसे लागू करता है। यदि आप एक enum और एक बड़ा switch का उपयोग करते हैं, तो यह सुनिश्चित नहीं करेगा कि आपने हर मामले को संभाला है।

  2. आप नए मामले (अपने उदाहरण में जानवरों के प्रकार) जोड़ सकते हैं। यह स्रोत फ़ाइलों, और यहां तक ​​कि पैकेज सीमाओं में भी किया जा सकता है। एक enum के साथ, एक बार जब आप इसे घोषित कर दिया है, यह जमे हुए है। ओपन-एंड एक्सटेंशन ओओपी की प्राथमिक शक्तियों में से एक है।

यह ध्यान रखना महत्वपूर्ण है कि आपके सहयोगी का उदाहरण आपके प्रत्यक्ष विरोध में नहीं है।वह एक जानवर के प्रकार एक उजागर संपत्ति (जो कुछ बातों के लिए उपयोगी है) बनना चाहता है, तो आप अभी भी कर सकते हैं कि एक enum का उपयोग कर, का उपयोग किए बिना type object pattern:

public abstract class AnimalType { 
    public static AnimalType Unknown { get; private set; } 
    public static AnimalType Cat { get; private set; } 
    public static AnimalType Dog { get; private set; } 

    static AnimalType() { 
     Unknown = new AnimalType("Unknown"); 
     Cat = new AnimalType("Cat"); 
     Dog = new AnimalType("Dog"); 
    } 
} 

public class Animal { 
    public AnimalType Type { get; set; } 
} 

यह आपको एक enum की सुविधा देता है: आप AnimalType.Cat कर सकते हैं और आप एक जानवर का प्रकार प्राप्त कर सकते हैं। लेकिन यह आपको कक्षाओं की लचीलापन भी देता है: आप AnimalType पर फ़ील्ड जोड़ सकते हैं ताकि प्रत्येक प्रकार के साथ अतिरिक्त डेटा स्टोर किया जा सके, आभासी तरीकों को जोड़ा जा सके। अधिक महत्वपूर्ण बात यह है कि आप AnimalType के नए उदाहरण बनाकर नए जानवरों के प्रकार को परिभाषित कर सकते हैं।

7

मैं तुम्हें पुनर्विचार करने के लिए आग्रह करता हूं चाहते हैं: एक anemic domain model (ऊपर टिप्पणी प्रति) में, बिल्लियों नहीं अलग तरह से कुत्तों की तुलना व्यवहार करते हैं, इसलिए कोई बहुरूपता है। एक जानवर का प्रकार वास्तव में सिर्फ एक विशेषता है। यह देखना मुश्किल है कि आपको कौन सी विरासत खरीदती है।

+2

धन्यवाद .. "बिल्लियों कुत्तों से अलग व्यवहार नहीं करते हैं, इसलिए कोई बहुलकता नहीं है।" एक बहुत अच्छा तर्क प्रतीत होता है। – Lijo

+3

बिल्लियों हालांकि छाल नहीं है ... –

1

दोनों समाधान सही हैं। आपको देखना चाहिए कि कौन सी तकनीकें आपको समस्या के लिए बेहतर लागू करती हैं।

यदि आपका प्रोग्राम कुछ अलग-अलग ऑब्जेक्ट्स का उपयोग करता है, और नई कक्षाएं नहीं जोड़ता है, तो यह गणनाओं के साथ रहने के लिए बेहतर है।

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

5

एक enum होने के कारण उन सभी Open/Closed Principle is for suckers लोगों के लिए पार्टी फेंकना है।

यह वास्तव में आपको यह जांचने के लिए आमंत्रित करता है कि कोई जानवर एक निश्चित प्रकार का है या फिर प्रत्येक प्रकार के लिए कस्टम तर्क लागू करें। और वह भयानक कोड प्रस्तुत कर सकता है जो आपके सिस्टम पर निर्माण जारी रखना वाकई मुश्किल बनाता है।

+0

कटाक्ष के लिए +1। –

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^