विभिन्न स्रोत प्रकारों और विभिन्न गंतव्य प्रकारों के डेटा आयात के लिए डिज़ाइन पैटर्न


14

मुझे एक आयात स्क्रिप्ट डिजाइन और निर्माण करना है (C # में) जो निम्नलिखित को संभाल सकती है:

  • विभिन्न स्रोतों से डेटा पढ़ें (XML, XSLX, CSV)
  • डेटा को सत्यापित करे
  • डेटा को विभिन्न ऑब्जेक्ट प्रकारों में लिखें (ग्राहक, पता)

डेटा कई स्रोतों से आएगा लेकिन एक स्रोत में हमेशा एक आयात प्रारूप होगा (या तो csv, xml, xslx)। आयात प्रारूप स्रोत से स्रोत तक भिन्न हो सकते हैं। भविष्य में नए आयात प्रारूप जोड़े जा सकते हैं। गंतव्य ऑब्जेक्ट प्रकार हमेशा समान होते हैं (ग्राहक, अतिरिक्त और कुछ और)।

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

इस समस्या को हल करने के लिए एक उपयुक्त डिजाइन पैटर्न क्या है?


इसे सरल रखें।
NoChance

जवाबों:


11

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

इसे सरल रखें। मौलिक प्रथाओं का उपयोग करें।

  1. XML के लिए एक रीडिंग करने के बीच की सामान्य चीजों की कल्पना करने की कोशिश करें, जो कि CSV के लिए एक रीड है। चीजें, अगले रिकॉर्ड, अगली पंक्ति। चूंकि नए प्रारूप जोड़े जा सकते हैं, सामान्यता की कल्पना करने की कोशिश करें कि निर्धारित प्रारूप को ज्ञात लोगों के साथ होना चाहिए। इस समानता का उपयोग करें और एक 'इंटरफ़ेस' या एक अनुबंध को परिभाषित करें जिसे सभी प्रारूपों का पालन करना होगा। हालांकि वे आम जमीन का पालन करते हैं, वे सभी अपने विशिष्ट आंतरिक नियम हो सकते हैं।

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

  3. डेटा निर्माणों के निर्माण के लिए आप संभवतः किसी भी चीज़ से अधिक सुझाए गए आउटपुट ऑब्जेक्ट को डिज़ाइन करने के लिए बाध्य होंगे। यह जानने की कोशिश करें कि डेटा ऑब्जेक्ट के लिए अगला चरण क्या है, और क्या कोई अनुकूलन है जिसे आप अंतिम उपयोग को जानकर कर सकते हैं। उदाहरण के लिए यदि आप जानते हैं कि वस्तुओं का उपयोग एक इंटरैक्टिव अनुप्रयोग में किया जा रहा है, तो आप उस एप्लिकेशन के डेवलपर को ऑब्जेक्ट्स या अन्य प्रकार की व्युत्पन्न जानकारी के 'सारांश' या गिनती प्रदान करके मदद कर सकते हैं।

मैं कहूंगा कि इनमें से अधिकांश टेम्पलेट पैटर्न या रणनीति पैटर्न हैं। पूरी परियोजना एक एडेप्टर पैटर्न होगी।


+1, विशेष रूप से पहले पैराग्राफ के लिए (और यह देखना अच्छा है कि आप अंतिम पैराग्राफ में मेरे लिए समान निष्कर्ष पर आए)।
डॉक्टर ब्राउन

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

इसे सुविधाजनक बनाने के लिए, न केवल टुकड़ों के अपने आंतरिक अनुबंध होने चाहिए, जिसका वे पालन करते हैं, ऐसे अनुबंधों का एक सेट होना चाहिए जो टुकड़ों के बीच बातचीत को परिभाषित करता है ।
एंडीज स्मिथ

@AndyzSmith - मुझे अपने कोड में समान समस्या है। एडॉप्टर पैटर्न को छोड़कर मुझे आपके कोड के बारे में सब समझ में आया। जब आपने कहा कि पूरी परियोजना अडैप्टर पैटर्न का एक उदाहरण है तो क्या आप इसका उदाहरण दे सकते हैं?
गन्सब

9

स्पष्ट बात यह है कि रणनीति पैटर्न लागू करना है । एक जेनेरिक बेस क्लास रखें ReadStrategyऔर प्रत्येक इनपुट फॉर्मेट के लिए एक उपवर्ग जैसे XmlReadStrategy, CSVReadStrategyआदि। यह आपको वर्फिकेशन प्रोसेसिंग और आउटपुट प्रोसेसिंग से स्वतंत्र रूप से आयात प्रसंस्करण को बदलने की अनुमति देगा।

विवरण के आधार पर आयात जेनेरिक के अधिकांश हिस्सों को रखना और इनपुट प्रोसेसिंग के केवल कुछ हिस्सों का आदान-प्रदान करना संभव हो सकता है (उदाहरण के लिए, एक रिकॉर्ड को पढ़ना)। यह आपको खाका विधि पैटर्न की ओर ले जा सकता है ।


क्या इसका मतलब है कि रणनीति पैटर्न का उपयोग करते समय, मुझे वस्तुओं (ग्राहक, पते) को स्रोत से गंतव्य तक परिवर्तित करने के लिए अलग-अलग तरीके बनाने होंगे। मैं क्या करना चाहूंगा, प्रत्येक ऑब्जेक्ट को पढ़ना, परिवर्तित करना और मान्य करना और इसे एक सूची में डालना ताकि सूची को बाद में डेटाबेस में सहेजा जा सके।
जौ

@ जओ: ठीक है, यदि आप मेरे उत्तर को फिर से पढ़ते हैं, तो आप देखते हैं कि मेरा सुझाव "ReadStrategy" बनाना था, न कि "ConvertStrategy"। इसलिए आपको केवल वस्तुओं को पढ़ने के लिए अलग-अलग तरीकों को लिखना होगा (या आपकी प्रक्रिया का अतिरिक्त हिस्सा विशिष्ट फ़ाइल प्रारूप के लिए अलग-अलग है)।
डॉक्टर ब्राउन

7

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

प्रत्येक MEF भाग को कुछ मानक विधियों के साथ एक आयात इंटरफ़ेस को संतुष्ट करने के लिए बनाया जा सकता है, जो आयात फ़ाइल की एक पंक्ति को आपके आउटपुट डेटा में परिवर्तित करते हैं या मूल कार्यक्षमता के साथ बेस क्लास को ओवरराइड करते हैं।

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

MEF (प्रबंधित एक्स्टेंसिबिलिटी फ्रेमवर्क) ऐप बनाने के लिए एक संदर्भ के साथ शुरू होता है System.ComponentModel.Composition

यह निर्धारित करने के लिए इंटरफेस को परिभाषित करें कि कनवर्टर क्या करेगा

public interface IImportConverter
{
    int UserId { set; }        
    bool Validate(byte[] fileData, string fileName, ImportType importType);
    ImportResult ImportData(byte[] fileData, string fileName, ImportType importType);
}

यह उन सभी फ़ाइल प्रकारों के लिए उपयोग किया जा सकता है जिन्हें आप आयात करना चाहते हैं।

एक नए वर्ग में विशेषताएँ जोड़ें जो परिभाषित करता है कि वर्ग "निर्यात" क्या करेगा

[Export(typeof(IImportConverter))]
[MyImport(ImportType.Address, ImportFileType.CSV, "4eca4a5f-74e0")]
public class ImportCSVFormat1 : ImportCSV, IImportConverter
{
 ...interface methods...
}

यह एक वर्ग को परिभाषित करेगा जो CSV फ़ाइलों को आयात करेगा (एक विशेष प्रारूप का: Format1) और इसमें एक कस्टम विशेषताएँ हैं जो MEF निर्यात विशेषता मेटाडेटा सेट करती हैं। आप इसे प्रत्येक प्रारूप या फ़ाइल प्रकार के लिए दोहराएंगे जिसे आप आयात करना चाहते हैं। आप वर्ग के साथ कस्टम विशेषताएँ सेट कर सकते हैं जैसे:

[MetadataAttribute]
[AttributeUsage(AttributeTargets.All, AllowMultiple = false)]
public class ImportAttribute : ExportAttribute
{
    public ImportAttribute(ImportType importType, ImportFileType fileType, string customerUID)
        : base(typeof(IImportConverter))
    {
        ImportType = importType;
        FileType = fileType;
        CustomerUID = customerUID;
    }

    public ImportType ImportType { get; set; }
    public ImportFileType FileType { get; set; }
    public string CustomerUID { get; set; }
}

वास्तव में MEF कन्वर्टर्स का उपयोग करने के लिए आपको आपके द्वारा बनाए गए MEF भागों को आयात करने की आवश्यकता होती है जब आपका परिवर्तित कोड चलाया जाता है:

[ImportMany(AllowRecomposition = true)]
protected internal Lazy<IImportConverter, IImportMetadata>[] converters { get; set; }
AggregateCatalog catalog = new AggregateCatalog();

catalog फ़ोल्डर से भागों को इकट्ठा करता है, डिफ़ॉल्ट ऐप लोकेशन है।

converters आयातित MEF भागों की एक आलसी सूची है

फिर जब आप जानते हैं कि आप किस प्रकार की फ़ाइल को परिवर्तित करना चाहते हैं ( importFileTypeऔर importType) आयातित भागों की सूची से एक कनवर्टर प्राप्त करते हैंconverters

var tmpConverter = (from x in converters
                    where x.Metadata.FileType == importFileType
                    && x.Metadata.ImportType == importType 
                    && (x.Metadata.CustomerUID == import.ImportDataCustomer.CustomerUID)
                    select x).OrderByDescending(x => x.Metadata.CustomerUID).FirstOrDefault();

if (tmpConverter != null)
{
     var converter = (IImportConverter)tmpConverter.Value;
     result = converter.ImportData(import.ImportDataFile, import.ImportDataFileName, importType);
....
}

converter.ImportDataआयात करने वाली कॉल आयातित वर्ग में कोड का उपयोग करेगी।

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


मैंने पहले MEF के बारे में नहीं सुना है। यह क्या है?
जौ

2
@ जओ पूर्ण विवरण के लिए लिंक देखें । मेरे जवाब में कुछ उदाहरण MEF सामान जोड़े।
मैट

1
यह MEF में किक करने का एक शानदार तरीका है। +1
पाओकोगोमेज़

MEF एक तकनीक है, न कि एक डिज़ाइन पैटर्न। -1मेरे द्वारा कोई अंतर्निहित विचार अभी भी समझ में नहीं आता है और IImportConverterइंटरफ़ेस द्वारा शासित रणनीति पैटर्न पर निर्भर करता है।
गेटा

0

इस समस्या को हल करने के लिए एक उपयुक्त डिजाइन पैटर्न क्या है?

C # मुहावरों में ऐसा करने के लिए अंतर्निहित क्रमांकन ढांचे का उपयोग करना शामिल है। आप मेटाडेटा के साथ ऑब्जेक्ट्स एनोटेट करते हैं, और फिर अलग-अलग धारावाहिकों को इंस्टेंट करते हैं जो उन एनोटेशन का उपयोग करके डेटा को सही रूप में डालने के लिए चीर देते हैं, या इसके विपरीत।

Xml, JSON, और बाइनरी फॉर्म सबसे आम हैं, लेकिन मुझे आश्चर्य नहीं होगा यदि अन्य लोग पहले से ही आपके लिए उपभोग करने के लिए एक अच्छे पैक के रूप में मौजूद हैं।


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

मैं किसी एक्सेल फाइल की लाइन को ऑब्जेक्ट पर मैप कर सकता हूं, लेकिन मुझे XML और CSV रीडर्स के लिए उस तरीके को कॉपी और अडॉप्ट करना होगा। और मैं कोड को यथासंभव साफ रखना चाहता हूं ...
jao

@docBrown - कैसे? वैचारिक रूप से, Excel में कोशिकाओं की श्रृंखला में किसी वस्तु को मोड़ना वास्तव में इसे xml दस्तावेज़ में बदलने से अलग नहीं है।
तेलस्टिन

@Telastyn: आप कहते हैं कि आप XLSX प्रारूप को पढ़ने के लिए .NET फ्रेमवर्क के क्रमांकन ढांचे में निर्मित का उपयोग कर सकते हैं ? अगर यह सच होगा, तो ओपन एक्सएमएल एसडीके या एनपीओआई जैसी लाइब्रेरी अप्रचलित थीं।
डॉक्टर ब्राउन

@docbrown: मेरी क्षमायाचना, आप सही हैं - मैं यह भूल जाता हूं कि कोई भी सामान्य सीरियलाइज़र बेस क्लास नहीं है क्योंकि यह पहली चीज़ है जो किसी भी कोडबेस में काम करता है, जिसमें मैं काम करता हूं।
Telastyn
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.