ORM परत पर अमूर्तता की परत बनाना


12

मेरा मानना ​​है कि यदि आपके पास आपकी रिपॉजिटरी एक ORM का उपयोग करती है जो डेटाबेस से पहले से ही पर्याप्त है।

हालाँकि, जहाँ मैं अब काम कर रहा हूँ, किसी का मानना ​​है कि हमारे पास एक ऐसी परत होनी चाहिए जो ओआरएम को अमूर्त कर दे, ताकि हम बाद में ओआरएम को बदलना चाहें।

क्या यह वास्तव में आवश्यक है या यह केवल एक परत बनाने के लिए बहुत सारे सिर पर है जो कई ओआरएम पर काम करेगा?

संपादित करें

बस अधिक विवरण देने के लिए:

  1. हमारे पास POCO क्लास और Entity Class हैं जिन्हें AutoMapper के साथ मैप किया जाता है। इकाई वर्ग का उपयोग रिपॉजिटरी परत द्वारा किया जाता है। रिपॉजिटरी लेयर तब एंटिटी फ्रेमवर्क के साथ संचार करने के लिए एब्सट्रैक्शन की अतिरिक्त परत का उपयोग करती है।
  2. व्यवसाय परत में किसी भी तरह से एंटिटी फ्रेमवर्क तक सीधी पहुंच नहीं है। ओआरएम पर अमूर्तता की अतिरिक्त परत के बिना भी, इस सेवा परत को उस उपयोगकर्ता परत का उपयोग करने की आवश्यकता है जो रिपॉजिटरी परत का उपयोगकर्ता है। दोनों ही स्थिति में, व्यावसायिक परत ORM से पूरी तरह से अलग हो जाती है।
  3. मुख्य तर्क भविष्य में ओआरएम को बदलने में सक्षम होना है। चूंकि यह वास्तव में रिपोजिटरी परत के अंदर स्थानीयकृत है, मेरे लिए, यह पहले से ही अच्छी तरह से अलग हो गया है और मुझे नहीं दिखता कि अमूर्त की एक अतिरिक्त परत को "गुणवत्ता" कोड की आवश्यकता क्यों है।

3
अतिरिक्त परत को औचित्य की आवश्यकता है, अन्यथा यह YAGNI का उल्लंघन करता है। दूसरे शब्दों में, किसी को विश्वास है कि आपको इसकी आवश्यकता है, यह साबित करने के लिए एक बोझ है कि
gnat

2
मैं समझ सकता हूं कि एक ऐसी डोमेन लेयर चाहिए जो केवल ऑपरेशन्स के वांछित उपसमुच्चय को उजागर करती है - ORMs एक सतह क्षेत्र को थोड़ा चौड़ा करते हैं (कहते हैं कि आप किसी ऐसी इकाई में अपडेट की अनुमति नहीं देना चाहते हैं जो किसी अन्य इकाई द्वारा निर्देशित नहीं है)। अमूर्त की ऐसी परत होने से इससे मदद मिलती है।
ओड

4
शायद आपको ओआरएम के ऊपर एब्सट्रैक्शन की पहली परत के लिए एब्सट्रैक्शन की दूसरी लेयर की आवश्यकता होगी, अगर आप पहली लेयर को भी बदलना चाहते हैं।
डेविड पेटरमैन

1
@ डेविड जब हम अतिरेक जोड़ रहे हैं, तो (boolean == true) और (यदि आप बूलियन == सच == सच ...) और अधिक को फिर से जोड़ना चाहते हैं, तो अपने सभी (बूलियन) को बदल दें। और इसके बाद
ब्रायन

1
रोचक संबंधित पोस्ट: ayende.com/blog/3955/repository-is-the-new-singleton
RMalke

जवाबों:


12

उस तरह से पागलपन है। यह अत्यधिक संभावना नहीं है कि आपको कभी भी ORM को बदलने की आवश्यकता होगी। और यदि आप कभी भी ओआरएम को बदलने का निर्णय लेते हैं, तो मैपिंग को फिर से लिखने की लागत आपके स्वयं के मेटा-ओआरएम को विकसित करने और बनाए रखने की लागत का एक छोटा सा हिस्सा होगी। मुझे उम्मीद है कि आप ORMs स्विच करने के लिए आवश्यक काम का 95% करने के लिए कुछ स्क्रिप्ट लिख सकते हैं।

इन-हाउस फ्रेमवर्क लगभग हमेशा एक आपदा है। भविष्य की जरूरतों की प्रत्याशा में एक निर्माण लगभग एक गारंटीकृत आपदा है। काल्पनिक आवश्यकताओं को पूरा करने के लिए समय से पहले निर्मित सफल परियोजनाओं से सफल रूपरेखाएं निकाली जाती हैं।


12

ORM आपकी RDBMS से स्वतंत्र होने के लिए आपकी डेटा लेयर के लिए एक अमूर्तता प्रदान करता है, लेकिन यह आपके डेटा लेयर से आपके व्यवसाय की परत को "खोल" देने के लिए पर्याप्त नहीं हो सकता है। विशेष रूप से, आपको उन वस्तुओं को आरडीबीएमएस तालिकाओं में मैप नहीं करना चाहिए जो सीधे व्यापार परत में "लीक" होती हैं।

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

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

आपकी रिपॉजिटरी के अंदर एक अतिरिक्त अमूर्त परत बनाने के साथ समस्या यह है कि ओआरएम का विशेष "ब्रांड" आपके साथ बातचीत करने के तरीके को निर्धारित करता है। यदि आप एक पतली आवरण का निर्माण करते हैं जो आपके ORM जैसा दिखता है, लेकिन आपके नियंत्रण में है, तो अंतर्निहित ORM को प्रतिस्थापित करना लगभग उतना ही कठिन होगा जितना कि उस अतिरिक्त परत के बिना होगा। यदि, दूसरी ओर, आप एक ऐसी परत का निर्माण करते हैं जो आपके ORM जैसा कुछ भी नहीं दिखता है, तो आपको ऑब्जेक्ट-रिलेशनल मैपिंग तकनीक की अपनी पसंद पर सवाल उठाना चाहिए।


मुझे बहुत खुशी हो रही है। NET ने इस समस्या को क्वैरी ऑब्जेक्ट को प्लेटफ़ॉर्म में सेंक कर हल किया है। हाइबरनेट का .NET पोर्ट भी इसका समर्थन करता है।
माइकल ब्राउन

2
@MikeBrown हाँ, और .NET ने LINQ तकनीक का उपयोग करते हुए, अपनी खुद की दो प्रतिस्पर्धी ORM तकनीकों की भी आपूर्ति की!
dasblinkenlight

@dasblinkenlight मैंने आपको अतिरिक्त जानकारी देने के लिए प्रश्न अपडेट किया।
पैट्रिक डेसजार्डिन्स

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

2

UnitOfWork आमतौर पर यह अमूर्तता प्रदान करता है। यह एक जगह है जिसे बदलने की आवश्यकता है, आपकी रिपॉजिटरी एक इंटरफेस के माध्यम से इस पर निर्भर करती है। यदि आपको कभी ओ / आरएम बदलने की आवश्यकता है, तो बस एक नया यूओडब्ल्यू लागू करें। एक और किया।

BTW यह सिर्फ O / RM को स्विच करने से आगे बढ़ता है, यूनिट टेस्टिंग के बारे में सोचें। मेरे पास तीन UnitOfWork कार्यान्वयन हैं, एक EF के लिए, एक NH के लिए (क्योंकि मुझे वास्तव में DID को ओरेकल / आरएमएस मिड-प्रोजेक्ट को एक क्लाइंट के लिए स्विच करना है जो ओरेकल का समर्थन चाहता था), और एक इनमेमोरी दृढ़ता के लिए। InMemory दृढ़ता यूनिट परीक्षण के लिए या यहां तक ​​कि इसके पीछे एक डेटाबेस डालने के लिए तैयार होने से पहले भी तेजी से प्रोटोटाइप के लिए एकदम सही था।

लागू करने के लिए रूपरेखा सरल है। सबसे पहले आपके पास अपना सामान्य IRepository इंटरफ़ेस है

public interface IRepository<T>
  where T:class
{
  IQueryable<T> FindBy(Expression<Func<T,Bool>>filter);
  IQueryable<T> GetAll();
  T FindSingle(Expression<Func<T,Bool>> filter);
  void Add(T item);
  void Remove(T item);

}

और IUnitOfWork इंटरफ़ेस

public interface IUnitOfWork
{
   IQueryable<T> GetSet<T>();
   void Save();
   void Add<T>(T item) where T:class;
   void Remove<T>(T item) where T:class;
}

अगला बेस रिपॉजिटरी है (इस पर आपकी पसंद अमूर्त होनी चाहिए या नहीं

public abstract class RepositoryBase<T>:IRepository<T>
  where T:class
{
   protected readonly IUnitOfWork _uow;

   protected RepositoryBase(IUnitOfWork uow)
   { 
      _uow=uow;
   }

   public IQueryable<T> FindBy(Expression<Func<T,Bool>>filter)
   {
      return _uow.GetSet<T>().Where(filter);
   }

   public IQueryable<T> GetAll()
   {
      return _uow.GetSet<T>();
   }

   public T FindSingle(Expression<Func<T,Bool>> filter)
   {
      return _uow.GetSet<T>().SingleOrDefault(filter);
   }

   public void Add(T item)
   {
      return _uow.Add(item);
   }

   public void Remove(T item)
   {
      return _uow.Remove(item);
   }
}

IUnitOfWork को लागू करना EF, NH और मेमोरी के लिए बच्चों का खेल है। जिस कारण से मैं आईक्यूएबल लौटाता हूं, उसी कारण से, आयेंडे ने अपने पोस्ट में उल्लेख किया, क्लाइंट आगे फ़िल्टर, सॉर्ट, ग्रुप और यहां तक ​​कि LINQ का उपयोग करके परिणाम को प्रोजेक्ट कर सकता है और आपको अभी भी इसका लाभ सभी सर्वर साइड हो रहा है।


1
लेकिन यहां प्रश्न यह निर्धारित कर रहा है कि ऊपर की परत उपयोगी है या नहीं और सभी डेटा एक्सेस के लिए द्वारपाल होना चाहिए।
ब्रायन

काश मैं कार्य / रिपोजिटरी कार्यान्वयन की इकाई पर अपने ब्लॉग पोस्ट को इंगित कर सकता। इसमें ओपी की सटीक चिंताओं पर चर्चा की गई है।
माइकल ब्राउन

परत को एक नाम देने का मतलब यह नहीं है कि यह आवश्यक या उपयोगी है।
केविन क्लाइन

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

आप एक कुशल ORM कॉल में मनमाने ढंग से अभिव्यक्ति का अनुवाद कैसे करते हैं? आप बस सब कुछ प्राप्त नहीं कर सकते हैं और उन पंक्तियों को फेंक सकते हैं जो फ़िल्टर से मेल नहीं खाती हैं।
केविन क्लाइन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.