2010-01-23 14 views
5

जब आप एक ऐसे एप्लिकेशन को लिख रहे हैं जिसे डेटा के दो संस्करणों के साथ पढ़ने और काम करने की आवश्यकता है, तो उस डेटा का प्रतिनिधित्व करने के लिए अपनी कक्षाओं को व्यवस्थित करने का सबसे अच्छा तरीका क्या है। मैं तीन परिदृश्य के साथ आए हैं:डेटा के विभिन्न संस्करणों को स्टोर करने का पसंदीदा तरीका क्या है?

  1. आम बेस/विशिष्ट बच्चे
  2. अलग संरचनाएं

संस्करण 1 कार उदाहरण

byte DoorCount 
int Color 
byte HasMoonroof 
byte HasSpoiler 
float EngineSize 
byte CylinderCount 

संस्करण 2 कार

  • डाटा संघ

    byte DoorCount 
    int Color 
    enum:int MoonRoofType 
    enum:int TrunkAccessories 
    enum:int EngineType 
    

    आम बेस/विशिष्ट बच्चे

    इस पद्धति से

    , डेटा के दो संस्करणों और डेटा के प्रत्येक संस्करण के लिए एक बच्चे के वर्ग के बीच आम क्षेत्रों में से एक आधार वर्ग है।

    class Car { 
        byte DoorCount; 
        int Color; 
    } 
    
    class CarVersion1 : Car { 
        byte HasMoonroof; 
        byte HasSpoiler; 
        float EngineSize; 
        byte CylinderCount; 
    } 
    
    class CarVersion2 : Car { 
        int MoonRoofType; 
        int TrunkAccessories; 
        int EngineType; 
    } 
    

    शक्तियों

    • OOP प्रतिमान

    कमजोरियों

    • मौजूदा बच्चे कक्षाओं को बदलने के लिए होगा अगर एक नया संस्करण जारी किया जाता है कि एक आम क्षेत्र को हटा
    • एक कॉन्स के लिए डेटा एप्टुअल यूनिट को दो परिभाषाओं के बीच विभाजित किया जाता है क्योंकि किसी भी विभाजन के लिए अर्थपूर्ण नहीं है।

    डाटा संघ

    यहाँ, एक कार डेटा के सभी संस्करणों में कार के क्षेत्र के मिलन के रूप में परिभाषित किया गया है।

    class Car { 
        CarVersion version; 
        byte DoorCount; 
        int Color; 
        int MoonRoofType;  //boolean if Version 1 
        int TrunkAccessories; //boolean if Version 1 
        int EngineType;  //CylinderCount if Version 1 
        float EngineSize;  //Not used if Version2 
    } 
    

    शक्तियों

    • उम ... सब कुछ एक ही स्थान पर है।

    कमजोरियों

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

    अलग संरचनाएं

    यहाँ संरचनाओं एक दूसरे से कोई OOP रिश्ता है।हालांकि, दोनों कक्षाओं द्वारा इंटरफेस लागू किया जा सकता है यदि कोड उसी समय में उनका इलाज करने की अपेक्षा करता है।

    class CarVersion1 { 
        byte DoorCount; 
        int Color; 
        byte HasMoonroof; 
        byte HasSpoiler; 
        float EngineSize; 
        byte CylinderCount; 
    } 
    
    class CarVersion2 { 
        byte DoorCount; 
        int Color; 
        int MoonRoofType; 
        int TrunkAccessories; 
        int EngineType; 
    } 
    

    शक्तियों

    • स्पष्ट दृष्टिकोण
    • आसान बनाए रखने के लिए करता है, तो एक नया संस्करण जोड़ा जाता है या विरासत निकाल दिया जाता है।

    कमजोरियों

    • यह एक विरोधी पैटर्न है।

    क्या कोई बेहतर तरीका है जिसके बारे में मैंने नहीं सोचा था? यह शायद स्पष्ट है कि मैं आखिरी पद्धति का समर्थन करता हूं, लेकिन क्या पहला बेहतर है?

  • उत्तर

    1

    तीसरा विकल्प, प्रत्येक संस्करण के लिए अलग संरचनाएं, एक बुरा विचार या विरोधी पैटर्न क्यों है?

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

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

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

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

    +0

    ठीक है, शायद मैंने कहा कि आखिरी विकल्प एक विरोधी पैटर्न था क्योंकि यह "समान" वैचारिक वस्तु के दो प्रतिनिधित्वों के लिए बेस क्लास का उपयोग नहीं करता है। "यह शायद ही पता चला है कि बेस क्लास इसके उत्तराधिकारी के करीब है" - हाँ, मैं बस पद्धतियों का प्रदर्शन करने के लिए एक संक्षिप्त उदाहरण का विरोध करने की कोशिश कर रहा था। तो क्या मैं समझ रहा हूं कि आप तीसरे विकल्प की वकालत करेंगे और यदि आवेदन कोड लिखा गया था तो पहले की आवश्यकता होगी? –

    +0

    हां, यह मेरे (लंबे) उत्तर का एक शर्मनाक संक्षेप सारांश था। –

    +0

    मैं पूरी तरह से सहमत हूं। –

    1

    दूसरे दृष्टिकोण का उपयोग करें और इसे इंटरफेस के साथ बढ़ाएं। याद रखें कि आप कई इंटरफेस "संस्करण" को कार्यान्वित कर सकते हैं जो आपको पिछड़े संगतता की शक्ति देता है! मैं आशा है कि आप मिल जाएगा मैं क्या कह करने के लिए होती;)

    1

    निम्न आवश्यकता पर जा रहे हैं:

    एक आवेदन पढ़ सकते हैं और एक ही तरीके से डेटा के दो संस्करणों के साथ काम करने की जरूरत है कि

    मैं कहूंगा कि सबसे महत्वपूर्ण बात यह है कि आप डेटा एब्स्ट्रक्शन लेयर के माध्यम से सभी तर्कों को फ़नल करते हैं, ताकि आपके तर्क में से कोई भी इस बात पर ध्यान न दे कि आप संस्करण 1, 2 या n डेटा का उपयोग कर रहे हैं या नहीं ।

    ऐसा करने का एक तरीका केवल एक डेटा वर्ग होना है, जो डेटा का सबसे अधिक "buffed up" संस्करण है। असल में, यह MoonRoofType होगा, लेकिन HasMoonRoof नहीं है क्योंकि इसका अनुमान लगाया जा सकता है।इस वर्ग में कोई भी अप्रचलित गुण नहीं होना चाहिए, क्योंकि यह तय करने के लिए डेटा अबास्ट्रक्शन लेयर पर निर्भर करता है कि डिफ़ॉल्ट मान क्या होना चाहिए।

    अंत में, आपके पास एक ऐसा एप्लिकेशन होगा जो डेटा संस्करणों की परवाह नहीं करता है।

    डेटा अबास्ट्रक्शन परत के लिए, आप प्रत्येक संस्करण के लिए डेटा कक्षाएं लेना चाहेंगे या नहीं। सबसे अधिक संभावना है कि आपको अपने आवेदन तर्क द्वारा उपयोग किए गए डेटा उदाहरणों को संग्रहीत/बनाने के लिए Save और Load विधियों के साथ डेटा संरचना के प्रत्येक संस्करण के लिए एक वर्ग की आवश्यकता होगी।

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

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