6

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

मैंने एक व्यापार परत बनाई है जिसमें अनुबंध और कार्यान्वयन शामिल हैं। कार्यान्वयन के बाद अन्य अनुबंधों पर निर्भरता हो सकती है और इसी तरह। यह डीओ के साथ एक आईओसी कंटेनर के माध्यम से संभाला जाता है। एक सेवा है जो DataAccess को संभालती है और यह सब एक यूनिटऑफवर्क लौटाती है। यह यूनिटऑफवर्क एक लेनदेन बनाता है जब कमेटी विधि पर डेटा को बढ़ाया जाता है और करता है। [View this Article (Testability and Entity Framework 4.0)]:

public interface IUnitOfWork : IDisposable { 
    IRepository<T> GetRepository<T>() where T : class; 
    void Commit(); 
} 

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

public interface IRepository<T> where T : class { 
    IQueryable<T> Table { get; } 
    void Add(T entity); 
    void Remove(T entity); 
} 

डेटा स्रोत सारणित होने पर, IQueryable अभी भी मुझे व्यवसाय तर्क के भीतर कहीं भी क्वेरी बनाने की क्षमता देता है। यहाँ एक उदाहरण है।

public interface IFoo { 
    Bar[] GetAll(); 
} 

public class FooImpl : IFoo { 
    IDataAccess _dataAccess; 
    public FooImpl(IDataAccess dataAccess) { 
     _dataAccess = dataAccess; 
    } 

    public Bar[] GetAll() { 
     Bar[] output; 
     using (var work = _dataAccess.DoWork()) { 
      output = work.GetRepository<Bar>().Table.ToArray(); 
     } 
     return output; 
    } 
} 

अब आप देख सकते हैं कि आप जटिल फ़िल्टर के साथ जुड़ने के साथ-साथ प्रश्नों को और अधिक जटिल कैसे प्राप्त कर सकते हैं।

इसलिए, मेरा प्रश्न हैं:

  1. इससे कोई फर्क पड़ता है BLL और दाल बीच कोई स्पष्ट भेद है कि वहाँ?
  2. क्या रेमोजिटरी परत के पीछे पूछताछ योग्यता डेटा पहुंच या व्यावसायिक तर्क माना जाता है जो इनमेमरी अबास्ट्रक्शन की तरह कार्य करता है?

अतिरिक्त: जितना अधिक मैं इसके बारे में सोचता हूं, शायद दूसरा प्रश्न केवल यही था जिसे पूछा जाना चाहिए था।

उत्तर

6

मुझे लगता है कि सबसे अच्छा तरीका है आपके सवालों के जवाब के लिए एक क्षण रुकें और पर विचार क्यों व्यापार तर्क परतों और डेटा का उपयोग परतों के बीच अलगाव की सिफारिश की प्रथा है के लिए है।

मेरे दिमाग में, कारण सरल हैं: व्यापार तर्क को डेटा परत से अलग रखें क्योंकि व्यापार तर्क वह है जहां मूल्य है, डेटा परत और व्यावसायिक तर्क को प्रत्येक के लिए स्वतंत्र रूप से समय के साथ बदलना होगा अन्य, और व्यापार तर्क को सभी डेटा एक्सेस परत के बारे में विस्तृत जानकारी प्राप्त किए बिना पठनीय होने की आवश्यकता है।

तो आपकी क्वेरी जिमनास्टिक के लिए लिटमस टेस्ट इस करने पर निर्भर करता:

  1. आप व्यापार तर्क का एक महत्वपूर्ण भाग परेशान बिना आपके सिस्टम में डेटा स्कीमा में होने वाले बदलाव कर सकते हैं?
  2. क्या आपका व्यवसाय तर्क आपके और अन्य सी # डेवलपर्स के लिए पठनीय है?
+1

+1 पहले बिंदु के लिए, खासकर – arootbeer

+2

+1। पहले उद्देश्य, दर्शन दूसरा। –

+0

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

1

1. सिर्फ अगर आप काम करने के तुलना में दर्शन के बारे में अधिक ध्यान रखते हैं। :)

2. मैं कहूंगा कि यह व्यवसाय तर्क है क्योंकि आपके बीच एक अमूर्तता है। मैं डीएएल के उस भंडार परत भाग को कॉल करता हूं, और जो कुछ भी इसका उपयोग करता है, बीएल।

लेकिन हाँ, इस रूप में अच्छी तरह से मेरे लिए अस्पष्ट है। मुझे नहीं लगता कि यह महत्वपूर्ण है। इस तरह पैटर्न का उपयोग की बात एक साफ, प्रयोग करने योग्य कोड है कि आसान एक ही समय में संवाद करने के लिए लिखने के लिए है, और उस लक्ष्य को किसी भी तरह से पूरा किया है।

1

1.Does इससे कोई फर्क BLL और दाल बीच कोई स्पष्ट भेद है कि वहाँ ?.

यह निश्चित रूप से मायने रखता है! आपके टेबल प्रॉपर्टी का उपयोग करने वाले किसी भी प्रोग्रामर को रैमिकेशंस (डेटाबेस राउंडट्रिप, क्वेरी अनुवाद, ऑब्जेक्ट ट्रैकिंग) को समझने की आवश्यकता होती है। यह व्यवसाय तर्क वर्गों को पढ़ने वाले प्रोग्रामर के लिए भी जाता है।

2.Is queryability माना डेटा एक्सेस या व्यापार तर्क है जब एक भंडार परत है कि एक InMemory अमूर्त तरह काम करता है के पीछे?

एब्स्ट्रक्शन एक कंबल है जिसे हम अपनी समस्याओं को छुपाते हैं।

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

हालांकि, abstractions रिसाव। यदि आप डेटा की दुनिया में समझने वाले प्रश्नों को चाहते हैं, तो अबास्ट्रक्शन के ऊपर और परे काम करने के लिए प्रयास करना चाहिए। वह अतिरिक्त प्रयास (जो अमूर्तता को हराता है) डेटा एक्सेस कोड उत्पन्न करता है।


कुछ उदाहरण:

output = work.GetRepository<Bar>().Table.ToArray(); 

इस कोड (संक्षेप में) ठीक है। लेकिन डेटा दुनिया में यह एक पूरी मेज स्कैनिंग में परिणाम देता है और (कम से कम आम तौर पर) गूंगा है!


badquery = work.GetRepository<Customer>().Table.Where(c => c.Name.Contains("Bob")).ToArray(); 
goodquery = work.GetRepository<Customer>().Table.Where(c => c.Name.StartsWith("Bob")).ToArray(); 

Goodquery बुरा क्वेरी की तुलना में बेहतर है जब वहाँ Customer.Name पर एक सूचकांक है। लेकिन यह तथ्य हमारे लिए तब तक उपलब्ध नहीं है जब तक हम अमूर्तता को उठाते हैं।


badquery = work.GetRepository<Customer>().Table 
    .GroupBy(c => c.Orders.Count()) 
    .Select(g => new 
    { 
    TheCount = g.Key, 
    TheCustomers = g.ToList() 
    }).ToArray(); 
goodquery = work.GetRepository<Customer>().Table 
    .Select(c => new {Customer = c, theCount = c.Orders.Count()) 
    .ToArray() 
    .GroupBy(x => x.theCount) 
    .Select(g => new 
    { 
    TheCount = g.Key, 
    TheCustomers = g.Select(x => x.Customer).ToList() 
    }) 
    .ToArray(); 

goodquery, के बाद से badquery समूह कुंजी के द्वारा डेटाबेस requery होगा बुरा क्वेरी से बेहतर है प्रत्येक समूह के लिए (और बुरा, यह अत्यधिक संभावना नहीं c.Orders.Count() करके ग्राहकों को छानने के साथ मदद करने के लिए एक सूचकांक है) है।


Testability भंडार डिजाइन में बनाया गया है।उम्मीदों के साथ परिणामों का दावा करने के लिए हम इनमेमारी कार्यान्वयन का लाभ उठा सकते हैं।

कोई भ्रम नहीं है कि आपके प्रश्नों का परीक्षण किया जा रहा है यदि आप वास्तव में इन-मेमोरी संग्रह के खिलाफ उन्हें चलाते हैं। जब तक डेटाबेस शामिल नहीं होता है तब तक वे प्रश्न अवांछित होते हैं।

+0

इसके बारे में सोचने के बाद, मैं एब्स्ट्रक्शन पर आपका बिंदु समझ रहा हूं रिसाव के। हालांकि IQueryable का स्रोत सारणित किया जा रहा है, व्यापार तर्क परत पर बनाई गई कोई भी क्वेरी ईएफ 4 द्वारा की जाने वाली स्क्रिप्ट को प्रभावी ढंग से बना रही है। इस प्रकार रिसाव। तो मेरा अगला प्रश्न यहां है, तो आलसी लोडिंग के साथ IQueryable को कभी भी डीएएल के बाहर उजागर किया जाना चाहिए? एक अलग तरीके से वाक्यांश दिया गया है, क्या EF4 ऑब्जेक्टसेट को डीबी के साथ एक खुला कनेक्शन कभी डीएएल से बाहर समझा जाना चाहिए? –

+0

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

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