रिपोजिटरी पैटर्न बनाम डीएएल


93

क्या ये एक ही चीज हैं? रॉब कॉनरी के स्टोरफ्रंट ट्यूटोरियल को देखने के लिए बस समाप्त हो गया और वे समान टेचीनीस लग रहे हैं। मेरा मतलब है, जब मैं एक डीएएल ऑब्जेक्ट लागू करता हूं तो मेरे पास गेटस्टफ, ऐड / डिलीट आदि तरीके हैं और मैं हमेशा इंटरफ़ेस पहले लिखता हूं ताकि बाद में डीबी को स्विच कर सकूं।

क्या मैं भ्रमित कर रहा हूँ?

जवाबों:


88

आप निश्चित रूप से चीजों को भ्रमित करने वाले नहीं हैं। :-)

मुझे लगता है कि प्रश्न का उत्तर इस बात पर निर्भर करता है कि आप कितना शुद्ध बनना चाहते हैं।

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

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

कुछ लोग रिपॉजिटरी पर अधिक डीडीडी अवरोध डालेंगे, जबकि अन्य डेटाबेस और सेवा परत के बीच एक सुविधाजनक मध्यस्थ के रूप में रिपॉजिटरी का उपयोग करेंगे। एक DAL की तरह एक रिपॉजिटरी डेटा एक्सेस बारीकियों से सेवा परत को अलग करती है।

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

public interface IRepository : IDisposable
{
    T[] GetAll<T>();
    T[] GetAll<T>(Expression<Func<T, bool>> filter);
    T GetSingle<T>(Expression<Func<T, bool>> filter);
    T GetSingle<T>(Expression<Func<T, bool>> filter, List<Expression<Func<T, object>>> subSelectors);
    void Delete<T>(T entity);
    void Add<T>(T entity);
    int SaveChanges();
    DbTransaction BeginTransaction();
}

क्या यह डीएएल या भंडार है? इस मामले में मुझे इसका दोनों अनुमान है।

किम


5
पार्टी के लिए देर से यहाँ, लेकिन क्यों टी [], सूची <टी> (या समान) नहीं?
माइक किंग्सकोट

27
शायद IEnumerable <T> सबसे अच्छा होगा।
वेनमो

9
या IQueryable <T>
kenwarner

1
मुझे लगता है कि IQueryable <T> सबसे अच्छा विकल्प होगा, क्योंकि यह आपको चैन के तरीकों और डिफर निष्पादन के लिए डेटाबेस को सभी काम करने देता है।
लुकाज़ 0

4
@kenwarner मुझे लगता है कि लौटने पर IQueryable <T> अमूर्त लीक करता है। आपको अपनी रिपॉजिटरी से डोमेन ऑब्जेक्ट वापस करना चाहिए।
मैथ्यू

42

एक रिपॉजिटरी एक पैटर्न है जिसे कई अलग-अलग तरीकों से लागू किया जा सकता है, जबकि डेटा एक्सेस लेयर पर बहुत स्पष्ट जिम्मेदारी है: DAL को यह पता होना चाहिए कि CRUD ऑपरेशन करने के लिए अपने डेटा स्टोरेज से कैसे कनेक्ट करें।

एक रिपॉजिटरी एक डीएएल हो सकती है, लेकिन यह डीएएल के सामने भी बैठ सकती है और बिजनेस ऑब्जेक्ट लेयर और डेटा लेयर के बीच एक सेतु का काम कर सकती है। किस कार्यान्वयन का उपयोग प्रोजेक्ट से प्रोजेक्ट में भिन्न हो रहा है।


23

एक बड़ा अंतर यह है कि एक डीएओ आपके डोमेन में किसी भी इकाई के लिए दृढ़ता से निपटने का एक सामान्य तरीका है। दूसरी ओर एक भंडार केवल सकल जड़ों से संबंधित है।


26
समझने वाली पहली बात यह है कि एक पैटर्न के रूप में एक रिपॉजिटरी डोमेन ड्रिवेन डिज़ाइन के रूप में ज्ञात बड़ी प्रणाली का हिस्सा है। DDD में डोमेन ऑब्जेक्ट्स को एग्रीगेट रूट के साथ एग्रीगेट में वर्गीकृत किया जाता है। Eg PurchaseOrder एक कुल जड़ है और OrderItems कुल जड़ के भीतर बच्चे हैं। एक भंडार केवल समग्र जड़ों से संबंधित है। उदाहरण के लिए, ऑर्डरआइटम कभी भी स्वतंत्र रूप से लोड नहीं होता है, यह एग्रीट रूट है। तो, आपके पास डीडीडी में ऑर्डरआइटम भंडार नहीं होगा। हालाँकि, एक गैर-DDD प्रणाली में आप एक OrderItemDao कर सकते हैं क्योंकि डाओ कुल जड़ों तक सीमित नहीं है।
२३:०३ पर विचारोत्तेजक

एनजी, धन्यवाद! मैंने इसे इस तरह से देखना शुरू कर दिया था, लेकिन इससे यह स्पष्ट हो जाता है। मुझे सभी डीडीडी साहित्य पढ़ना शुरू करना होगा!
डेविड

@ घिसावट, समग्र जड़ों का महान विवरण और कैसे बाल वस्तुओं को एक भंडार द्वारा लोड किया जाता है। बहुस्तरीय एप्लिकेशन में एक रिपॉजिटरी कहां मौजूद होगी? मैं इसे डेटा एक्सेस लेयर लाइब्रेरी में देख सकता था लेकिन चूंकि यह चाइल्ड ऑब्जेक्ट्स को लोड करता है, तो क्या इसके बजाय लॉजिक लेयर लाइब्रेरी में मौजूद होना चाहिए? मेरी आंत मुझे डेटा एक्सेस लेयर बताती है लेकिन मैं इस मामले पर आपकी राय चाहता था।
जेफ लाफे

12

मैं एक ऐसे ही प्रश्न के उत्तर की तलाश में था और दो सर्वोच्च रैंक वाले उत्तर से सहमत था। अपने लिए यह स्पष्ट करने की कोशिश करते हुए, मैंने पाया कि यदि रिपॉजिटरी पैटर्न के साथ हाथ से जाने वाले विनिर्देश, डोमेन मॉडल के प्रथम श्रेणी के सदस्यों के रूप में लागू किए जाते हैं, तो मैं कर सकता हूं

  • विभिन्न मापदंडों के साथ पुन: उपयोग की परिभाषाएँ,
  • मौजूदा विशिष्टता उदाहरणों के मापदंडों में हेरफेर करें (उदाहरण के लिए विशेषज्ञ),
  • उन्हें गठबंधन ,
  • किसी भी डेटाबेस का उपयोग किए बिना उन पर व्यावसायिक तर्क दें,
  • और निश्चित रूप से, यूनिट वास्तविक-रिपोजिटरी कार्यान्वयन से स्वतंत्र है।

मैं यहां तक ​​कह सकता हूं कि जब तक रिपॉजिटरी पैटर्न को स्पेसिफिकेशन पैटर्न के साथ एक साथ इस्तेमाल नहीं किया जाता है, यह वास्तव में "रिपॉजिटरी" नहीं है, बल्कि एक डीएएल है। छद्म कोड में एक आकस्मिक उदाहरण:

specification100 = new AccountHasMoreOrdersThan(100)
specification200 = new AccountHasMoreOrdersThan(200)

assert that specification200.isSpecialCaseOf(specification100)

specificationAge = new AccountIsOlderThan('2000-01-01')

combinedSpec = new CompositeSpecification(
    SpecificationOperator.And, specification200, specificationAge)

for each account in Repository<Account>.GetAllSatisfying(combinedSpec)
    assert that account.Created < '2000-01-01'
    assert that account.Orders.Count > 200

देखें फाउलर की विशिष्टता निबंध जानकारी के लिए (है कि क्या मैं पर ऊपर आधार पर)।

एक DAL जैसे विशेष तरीके होंगे

IoCManager.InstanceFor<IAccountDAO>()
    .GetAccountsWithAtLeastOrdersAndCreatedBefore(200, '2000-01-01')

आप देख सकते हैं कि यह कैसे जल्दी से बोझिल हो सकता है, खासकर जब से आपको इस दृष्टिकोण के साथ प्रत्येक डीएएल / डीएओ इंटरफेस को परिभाषित करना होगा और डीएएल क्वेरी विधि को लागू करना होगा।

.NET में, LINQ क्वेरी स्पेसिफिकेशन्स को लागू करने का एक तरीका हो सकता है, लेकिन स्पेसिफिकेशन (एक्सप्रेशंस) को संयोजित करना एक घरेलू समाधान की तरह सुचारू नहीं हो सकता है। इसके लिए कुछ विचार इस एसओ प्रश्न में वर्णित हैं ।


2

मेरी व्यक्तिगत राय है कि यह मानचित्रण के बारे में है, देखें: http://www.martinfowler.com/eaaCatalog/repository.html । इसलिए रिपॉजिटरी से आउटपुट / इनपुट डोमेन ऑब्जेक्ट हैं, जो कि DAL पर कुछ भी हो सकता है। मेरे लिए यह एक महत्वपूर्ण जोड़ / प्रतिबंध है, क्योंकि आप डेटाबेस / सेवा के लिए एक रिपॉजिटरी कार्यान्वयन जोड़ सकते हैं / जो कि एक अलग लेआउट के साथ है, और आपके पास मैपिंग करने पर ध्यान केंद्रित करने के लिए एक स्पष्ट स्थान है। यदि आप उस प्रतिबंध का उपयोग नहीं कर रहे थे और कहीं और मैपिंग कर रहे हैं, तो डेटा को दर्शाने के अलग-अलग तरीके होने से कोड उन जगहों पर प्रभावित हो सकता है जहां इसे बदलना नहीं चाहिए।


1

यह सब व्याख्या और संदर्भ के बारे में है। वे बहुत समान या वास्तव में बहुत भिन्न हो सकते हैं, लेकिन जब तक समाधान काम करता है, तब तक एक नाम में क्या है!


1

रिपॉजिटरी एक पैटर्न है, यह कोड को पुन: उपयोग करने के लिए मानकीकृत तरीके से चीजों को लागू करने का एक तरीका है।


1

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


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

0

जो मैं समझता हूं कि वे मूल रूप से एक ही चीज का अर्थ कर सकते हैं - लेकिन नामकरण संदर्भ के आधार पर भिन्न होता है।

उदाहरण के लिए, आपके पास एक Dal / Dao वर्ग हो सकता है जो एक IRepository इंटरफ़ेस लागू करता है।

दाल / दाओ एक डेटा लेयर टर्म है; आपके आवेदन के उच्च स्तर के प्रस्ताव के संदर्भ में सोचते हैं।


0

तो ज्यादातर (सरल) मामलों में DAO रिपॉजिटरी का कार्यान्वयन है?

जहां तक ​​मैं समझता हूं, ऐसा लगता है कि डीएओ डीबी पहुंच (सीआरयूडी - कोई चयन नहीं करता है, हालांकि) के साथ सटीक रूप से व्यवहार करता है; जबकि रिपॉजिटरी आपको पूरे डेटा एक्सेस को सार करने की अनुमति देती है, शायद कई डीएओ (शायद अलग-अलग डेटा स्रोत) के लिए एक मुखौटा।

क्या मैं सही रास्ते पर हूँ?


वास्तव में, मैं इसे उल्टा करूंगा और कहूंगा कि एक सरलीकृत दृष्टिकोण से, रिपॉजिटरी एक डीएओ के लिए एक विशेष कार्यान्वयन शैली है, लेकिन हां, आप सही रास्ते पर हैं। (आरयूडी से सीआरयूडी = पढ़ें, ताकि आपका चयन हो।)
जेरोमे इरविन

0

बाहरी दुनिया में (यानी क्लाइंट कोड) रिपॉजिटरी DAL के समान है, सिवाय:

(1) यह डेटा कंटेनर ऑब्जेक्ट को पैरामीटर के रूप में रखने के लिए सम्मिलित / अद्यतन / हटाता है।

(2) रीड ऑपरेशन के लिए यह एक डीएएल (उदाहरण के लिए GetByPK) या उन्नत विनिर्देशन की तरह सरल विनिर्देश ले सकता है।

आंतरिक रूप से यह वास्तविक CRUD ऑपरेशन करने के लिए एक डाटा मैपर लेयर (उदाहरण के लिए इकाई फ्रेमवर्क संदर्भ आदि) के साथ काम करता है।

रिपोजिटरी पैटर्न का क्या मतलब नहीं है: -

इसके अलावा, मैंने देखा है कि लोग अक्सर एक अलग सहेजें पद्धति के लिए भ्रमित होते हैं क्योंकि सम्मिलित / अद्यतन / हटाएं विधियों के अलावा रिपॉजिटरी पैटर्न नमूना कार्यान्वयन जो डेटाबेस में सम्मिलित / अद्यतन / हटाने के तरीकों से किए गए सभी इन-मेमोरी परिवर्तनों को करता है। हमारे पास एक रिपॉजिटरी में निश्चित रूप से एक सेव विधि हो सकती है, लेकिन यह इन-मेमोरी CUD (क्रिएट, अपडेट, डिलीट) और दृढ़ता तरीकों को अलग करने के लिए रिपॉजिटरी की जिम्मेदारी नहीं है (जो डेटाबेस में वास्तविक लेखन / परिवर्तन ऑपरेशन करता है), लेकिन कार्य पैटर्न की इकाई की जिम्मेदारी।

उम्मीद है की यह मदद करेगा!


0

कोई यह तर्क दे सकता है कि "रिपॉजिटरी" एक विशिष्ट वर्ग है और "डीएएल" पूरी परत है जिसमें रिपॉजिटरी, डीटीओ, यूटिलिटी क्लास और कुछ भी आवश्यक है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.