5

मैं स्क्रैच से काफी नई वेबसाइट प्रोजेक्ट लिख रहा हूं। परियोजना सी # में है, लेकिन मेरी पृष्ठभूमि PHP में है (नीचे छद्म कोड नीचे एक मिश्रण है, जो संक्षेप में और घोषणात्मक दोनों होने का प्रयास कर रहा है)।विभिन्न डेटा स्रोतों के लिए डेटा मैपर/रिपोजिटरी दृढ़ता पैटर्न को कैसे कार्यान्वित करें?

समस्या

मैं दो स्थानों में से एक से विन्यास डेटा पुनः प्राप्त करने की जरूरत है - स्थानीय डेटाबेस से और कभी कभी एक साबुन सेवा से कभी कभी। मैं किसी भी स्रोत से मॉडल ऑब्जेक्ट्स का एक ही सेट बनाने में सक्षम होना चाहिए।

डेटा विभिन्न डेटा स्रोतों में पूरी तरह से अलग संरचनाओं में संग्रहीत है - कई अलग साबुन प्रतिक्रियाओं को साबुन अंत से एक साथ पाई जाने की आवश्यकता है, जबकि डीबी संरचना मेरे मॉडल ऑब्जेक्ट्स को कैसे बना रही है इसके करीब है कोड।

विन्यास वस्तुओं की एक पेड़ से बना है: उत्पादगुण जो विकल्प है जो जब वे लागू के लिए स्थितियां शामिल होते हैं।

लक्ष्यों

मैं जितना संभव हो उतना (करने के लिए उम्मीद है कि दोनों परीक्षण/maintain-/विस्तार-क्षमता की सुविधा) चिंताओं को अलग करना चाहते:

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

प्रश्न

मैं इस भर के विभिन्न डिजाइन पैटर्न के बारे में पता कर रहा हूँ (हालांकि मैं पूरी तरह यकीन है कि मैं उन्हें पूरी तरह से समझ में नहीं हूँ)। मैं asked a question on Programmers इस तरह के समान था और Persistence Ignorance (more here) और Repository पैटर्न के बारे में प्रतिक्रिया मिली, जो दोनों माइक्रोसॉफ्ट दुनिया से अवधारणाएं प्रतीत होती हैं।

जहां तक ​​मेरा बता सकते हैं "हठ अज्ञान" बस मॉडल वस्तुओं है कि आपके डाटा संग्रहण तंत्र के बारे में कुछ भी नहीं पता होने की अवधारणा है, और भंडार पैटर्न बहुत डाटा मैपर पैटर्न के समान लगता है, कि यह may be more of a facade को छोड़कर, छुपा वास्तव में क्या चल रहा है।

तो मेरी प्रश्न हैं:

डाटा मैपर पैटर्न में मैं मॉडल वस्तु प्रति एक मैपर होना चाहिए? पूरे कॉन्फ़िगरेशन पेड़ के लिए एक होने के बजाय?

और इसलिए, क्या मेरे पास एक कॉन्फ़िगरेशन पेड़ निर्माण ऑब्जेक्ट होना चाहिए जो उन सभी मैपर ऑब्जेक्ट्स का उपयोग करता हो?

class ConfigBuilder() { 
    public ConfigBuilder (productMapper, propertyMapper, optionMapper, conditionMapper) { 
     // save them into local properties 
    } 

    public Products() { 
     var products = productMapper.FetchAll(); 

     foreach (var product in products) { 
      AddProperties(product); 
     } 

     return products; 
    } 

    private AddProperties(products) { /* ... */ } 
    private AddOptions(property) { /* ... */ } 
    private AddConditions(option) { /* ... */ } 
} 

क्या यह एक अच्छा समाधान जैसा प्रतीत होता है?

वस्तुओं को बनाने के लिए तर्क कहां स्थित होना चाहिए?

किसी बिंदु पर मेरे कॉन्फ़िगरेशन ऑब्जेक्ट्स को एक्सएमएल डेटा की यादृच्छिक सरणी से बनाने के लिए पर्याप्त मात्रा में तर्क होना आवश्यक है, जिसे मैं साबुन सेवा से वापस प्राप्त करता हूं, और तर्क से थोड़ी मात्रा में तर्क करता हूं डेटाबेस।

क्या मुझे मैपर ऑब्जेक्ट्स के अलग-अलग उदाहरणों में वस्तुओं को बनाने के लिए तर्क डालना चाहिए?

interface IProductMapper { FetchAll; FetchByCode; Create; Delete; Update } 

class ProductMapperXml implements IProductMapper { 
    public ProductMapperXml(xmlDataSource) {} 
    public FetchAll() { /* A whole bunch of logic to create the Product objects from XML data source */ } 
} 

class ProductMapperDatabase implements IProductMapper { 
    public ProductMapperDatabase(databaseConnection) {} 
    public FetchAll() { /* Select and build products from the database */ } 
} 

क्या यह ठीक है? क्या इस तर्क को आगे समझा जाना चाहिए? यदि ऐसा है तो क्यों? इसके अलावा, मैं ProductMapperXml ऑब्जेक्ट के बारे में काफी तर्कसंगत हूं, जिसमें ऑब्जेक्ट में काफी तर्क है और आंतरिक रूप से Product ऑब्जेक्ट्स बनाने के लिए जिम्मेदार भी है। क्या मुझे इसे किसी प्रकार के ProductFactory पास करना चाहिए? या बस एक कारखाने विधि का उपयोग करें?

कृपया मुझे बताएं कि क्या मेरे सुझावों से इसे हल करने के लिए और अधिक शानदार तरीके हैं? अगर अबास्ट्रक्शन या डिज़ाइन पैटर्न की कोई परतें भी हैं, तो मुझे इससे फायदा हो सकता है?

उत्तर

3

चूंकि कोई जवाब नहीं आ रहा है, इसलिए मैं इसे स्वयं लिखने जा रहा हूं।

मैं DataMapper पैटर्न के साथ जा रहा था - मुझे उम्मीद है कि मैंने इसे एक समझदार फैशन में लागू किया है।

मैंने किसी भी फैक्टरी वर्ग का उपयोग नहीं किया, क्योंकि मैं कक्षाओं के माध्यम से पेड़ बनाने में सक्षम था।

interface Models.Interfaces.IModel {} 
interface Mappers.Interfaces.IMapper {} 
interface Mappers.Interfaces.IDatabaseMapper : IMapper {} 
interface Mappers.Interfaces.IXmlMapper : IMapper {} 

मैं सब कुछ के लिए मॉडल बनाया:

मैं मैपर इंटरफेस का एक समूह बनाया

class Models.Product : IModel {} 
class Models.Property : IModel {} 
class Models.Option : IModel {} 
class Models.Condition : IModel {} 

और फिर मैं एक मॉडल के दो नक्शाकार कक्षाएं दिया:

class Mappers.ProductDatabaseMapper : IDatabaseMapper {} 
class Mappers.ProductXmlMapper : IXmlMapper {} 
/* ... (same for each model) */ 

प्रत्येक मैपर वर्ग में अपने बच्चों को बनाने के तरीके हैं:

class ProductDatabaseMapper :IDatabaseMapper { 
    public List<Product> FetchAllWithChildren { 
     var productRows = DbManager.FetchAll("Product"); 
     var products = List<Product>(); 

     foreach(var productRow in productRows) { 
      var product = new Product(productRow["Name"]); 
      product.Properties = PropertyManagerInstance.FetchAllWithChildren(product); 
      products.Add(product): 
     } 

     return products; 
    } 
} 

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