क्या सीरियलाइजेशन और डिसिएरलाइजेशन को सीरियल की जिम्मेदारी दी जानी चाहिए?


16

मैं वर्तमान में C # .NET एप्लिकेशन के कई मॉडल वर्गों के (पुनः) डिज़ाइन चरण में हूँ। (MVC के M के रूप में मॉडल)। मॉडल कक्षाओं में पहले से ही अच्छी तरह से डिज़ाइन किए गए डेटा, व्यवहार और अंतर्संबंधों के बहुत सारे हैं। मैं पायथन से C # के मॉडल को फिर से लिख रहा हूं।

पुराने पायथन मॉडल में, मुझे लगता है कि मैं एक मस्सा देखता हूं। प्रत्येक मॉडल जानता ही क्रमानुसार करने के लिए कैसे, और क्रमबद्धता तर्क है कुछ भी नहीं वर्गों में से किसी के व्यवहार के बाकी के साथ क्या करना है। उदाहरण के लिए, कल्पना करें:

  • Imageएक .toJPG(String filePath) .fromJPG(String filePath)विधि के साथ वर्ग
  • ImageMetaData.toString()और .fromString(String serialized)विधि के साथ वर्ग ।

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

एक वर्ग के लिए यह जानना आम बात है कि कैसे खुद को क्रमबद्ध और निर्जन करना है? या मुझे एक सामान्य पैटर्न याद आ रहा है?

जवाबों:


16

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

public class Image
{
    public void toJPG(String filePath) { ... }

    public Image fromJPG(String filePath) { ... }
}

लेकिन क्या होगा यदि आप इसे / पीएनजी से, और जीआईएफ से क्रमबद्ध करना चाहते हैं? अब क्लास बन गया

public class Image
{
    public void toJPG(String filePath) { ... }

    public Image fromJPG(String filePath) { ... }

    public void toPNG(String filePath) { ... }

    public Image fromPNG(String filePath) { ... }

    public void toGIF(String filePath) { ... }

    public Image fromGIF(String filePath) { ... }
}

इसके बजाय, मैं आमतौर पर निम्नलिखित के समान एक पैटर्न का उपयोग करना पसंद करता हूं:

public interface ImageSerializer
{
    void serialize(Image src, Stream outputStream);

    Image deserialize(Stream inputStream);
}

public class JPGImageSerializer : ImageSerializer
{
    public void serialize(Image src, Stream outputStream) { ... }

    public Image deserialize(Stream inputStream) { ... }
}

public class PNGImageSerializer : ImageSerializer
{
    public void serialize(Image src, Stream outputStream) { ... }

    public Image deserialize(Stream inputStream) { ... }
}

public class GIFImageSerializer : ImageSerializer
{
    public void serialize(Image src, Stream outputStream) { ... }

    public Image deserialize(Stream inputStream) { ... }
}

अब, इस बिंदु पर, इस डिजाइन के साथ एक चेतावनी यह है कि धारावाहिकों identityको उस वस्तु के बारे में जानना होगा जो इसे क्रमबद्ध कर रही है। कुछ कहेंगे कि यह खराब डिजाइन है, क्योंकि कार्यान्वयन कक्षा के बाहर लीक हो गया है। इसका जोखिम / इनाम वास्तव में आपके ऊपर है, लेकिन आप कुछ ऐसा करने के लिए कक्षाओं को थोड़ा मोड़ सकते हैं

public class Image
{
    public void serializeTo(ImageSerializer serializer, Stream outputStream)
    {
        serializer.serialize(this.pixelData, outputStream);
    }

    public void deserializeFrom(ImageSerializer serializer, Stream inputStream)
    {
        this.pixelData = serializer.deserialize(inputStream);
    }
}

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


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

बहुत अच्छी बात है। मैं उस बारे में सोच रहा था, लेकिन दिमाग खराब था। मैं कोड अपडेट कर दूंगा।
ज़ीमस

मेरा मानना ​​है कि चूंकि अधिक क्रमांकन प्रारूप समर्थित हैं (अर्थात ImageSerializerइंटरफ़ेस के अधिक कार्यान्वयन लिखे गए हैं), ImageSerializerइंटरफ़ेस को भी बढ़ने की आवश्यकता होगी। EX: एक नया प्रारूप वैकल्पिक संपीड़न का समर्थन करता है, पिछले वाले नहीं थे -> ImageSerializerइंटरफ़ेस में संपीड़न कॉन्फ़िगरेशन को जोड़ें । लेकिन फिर अन्य स्वरूपों को उन विशेषताओं के साथ जोड़ दिया जाता है जो उन पर लागू नहीं होते हैं। जितना अधिक मैं इसके बारे में सोचता हूं, कम मुझे लगता है कि विरासत यहां लागू होती है।
kdbanman

जबकि मैं समझता हूं कि आप कहां से आ रहे हैं, मुझे लगता है कि यह एक मुद्दा नहीं है, कुछ कारणों से। यदि यह एक मौजूदा छवि प्रारूप है, तो संभावना है कि धारावाहिक निर्माता पहले से ही जानता है कि संपीड़न स्तरों से कैसे निपटना है, और यदि यह एक नया है, तो आपको इसे वैसे भी लिखना होगा। एक समाधान, तरीकों को ओवरलोड करना है, कुछ ऐसा है void serialize(Image image, Stream outputStream, SerializerSettings settings);तो यह मौजूदा संपीड़न और मेटाडेटा तर्क को नए तरीके से वायर करने का मामला है।
झाइमस जूल

3

सीरियलाइजेशन एक दो भाग समस्या है:

  1. एक वर्ग उर्फ संरचना को तत्काल कैसे करें के बारे में ज्ञान ।
  2. वर्ग उर्फ यांत्रिकी को तत्काल करने के लिए आवश्यक जानकारी को कैसे बनाए / स्थानांतरित करें, इसके बारे में ज्ञान ।

जहां तक ​​संभव हो, संरचना को यांत्रिकी से अलग रखा जाना चाहिए । यह आपके सिस्टम की प्रतिरूपकता को बढ़ाता है। यदि आप अपनी कक्षा में # 2 पर जानकारी को दफन करते हैं तो आप प्रतिरूपकता को तोड़ देते हैं क्योंकि अब आपकी कक्षा को क्रमबद्धता के नए तरीकों (यदि वे साथ आते हैं) के साथ तालमेल बनाए रखने के लिए संशोधित होना चाहिए।

छवि क्रमांकन के संदर्भ में, आप क्रमांकन पर जानकारी को वर्ग से अलग रखेंगे और इसे एल्गोरिदम में रखेंगे जो क्रमबद्धता के प्रारूप को निर्धारित कर सकते हैं - यह, JPEG, PNG, BMP आदि के लिए अलग-अलग कक्षाएं यदि कल कोई नया है। क्रमांकन एल्गोरिथ्म बस आपके साथ आता है कि एल्गोरिथ्म और आपका वर्ग अनुबंध अपरिवर्तित रहता है।

आईपीसी के संदर्भ में, आप अपनी कक्षा को अलग रख सकते हैं और फिर क्रमिक रूप से (एनोटेशन / विशेषताओं द्वारा) जानकारी की घोषणा कर सकते हैं। फिर आपका क्रमांकन एल्गोरिथ्म तय कर सकता है कि क्या JSON, Google प्रोटोकॉल बफ़र्स या XML को क्रमांकन के लिए उपयोग करना है या नहीं। यह भी तय कर सकते हैं कि जैक्सन पार्सर या अपने कस्टम पार्सर का उपयोग करें या नहीं - ऐसे कई विकल्प हैं जो आप एक सहज फैशन में डिजाइन करते समय आसानी से प्राप्त करेंगे!


1
क्या आप मुझे एक उदाहरण दे सकते हैं कि कैसे उन दो चीजों को डिकोड किया जा सकता है? मुझे यकीन नहीं है कि मैं भेद को समझता हूं।
kdbanman
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.