ActiveRecord पैटर्न में कमियां क्या हैं?


30

मैं उत्सुक हूं कि डेटा एक्सेस / व्यावसायिक वस्तुओं के लिए ActiveRecord पैटर्न का उपयोग करने में क्या कमियां हैं। केवल एक ही जो मैं अपने सिर के ऊपर से सोच सकता हूं वह यह है कि यह सिंगल रिस्पॉन्सिबिलिटी सिद्धांत का उल्लंघन करता है, लेकिन एआर पैटर्न पर्याप्त है कि यह कारण अकेले "अच्छा पर्याप्त" प्रतीत नहीं होता है इसका उपयोग न करने का औचित्य साबित करने के लिए (निश्चित रूप से मेरे दृश्य को तिरछा किया जा सकता है क्योंकि अक्सर मैं किसी भी कोड के साथ काम नहीं करता हूं जो किसी भी ठोस सिद्धांतों का अनुसरण करता है)।

व्यक्तिगत रूप से मैं ActiveRecord का प्रशंसक नहीं हूं (रेल एप्लिकेशन पर एक रूबी लिखने के अपवाद के साथ, जहां एआर "प्राकृतिक" लगता है) क्योंकि ऐसा लगता है कि वर्ग बहुत अधिक कर रहा है, और डेटा एक्सेस केवल कक्षा तक नहीं होना चाहिए से निपटने। मैं व्यावसायिक वस्तुओं को लौटाने वाली रिपॉजिटरी का उपयोग करना पसंद करता हूं। अधिकांश कोड मैं ActiveRecord की भिन्नता का उपयोग करने के लिए काम करता है, के रूप में (मुझे नहीं पता कि विधि एक बूलियन क्यों है):

public class Foo
{
    // properties...

    public Foo(int fooID)
    {
        this.fooID = fooID;
    }

    public bool Load()
    {
        // DB stuff here...
        // map DataReader to properties...

        bool returnCode = false;
        if (dr.HasRows)
            returnCode = true;

        return returnCode;
    }
}

या कभी-कभी public static Foo FindFooByID(int fooID)खोजकर्ताओं के लिए एक तरीका होने का अधिक "पारंपरिक" तरीका और public void Save()बचत / अद्यतन करने के लिए कुछ की तर्ज पर ।

मुझे लगता है कि ActiveRecord आम तौर पर लागू करने और उपयोग करने के लिए बहुत सरल है, लेकिन यह जटिल अनुप्रयोगों के लिए बहुत आसान लगता है और आप एक रिपॉजिटरी में अपने डेटा एक्सेस लॉजिक को एन्कैप करके और अधिक मजबूत आर्किटेक्चर रख सकते हैं (इसका उल्लेख करने के लिए स्वैप करना आसान नहीं है) डेटा एक्सेस की रणनीतियाँ जैसे कि शायद आप Stored Procs + DataSets का उपयोग करते हैं और LINQ या कुछ पर स्विच करना चाहते हैं)

तो इस पैटर्न में और क्या कमियां हैं, जो यह तय करते समय विचार किया जाना चाहिए कि क्या ActiveRecord नौकरी के लिए सबसे अच्छा उम्मीदवार है?

जवाबों:


28

मुख्य दोष यह है कि आपकी "इकाइयां" अपने स्वयं के दृढ़ता के बारे में जानते हैं जो कई अन्य खराब डिजाइन निर्णयों की ओर ले जाती हैं।

अन्य मुद्दे यह है कि ज्यादातर सक्रिय रिकॉर्ड टूलकिट मूल रूप से अप्रत्यक्ष की शून्य परतों के साथ 1 से 1 टेबल क्षेत्रों के लिए मैप करते हैं। यह छोटे पैमानों पर काम करता है, लेकिन जब आप को हल करने के लिए मुश्किल समस्याएँ आती हैं, तो यह अलग हो जाता है।


ठीक है, अपनी वस्तुओं को उनकी दृढ़ता के बारे में जानने का मतलब है कि आपको कुछ करने की आवश्यकता है:

  • आसानी से हर जगह डेटाबेस कनेक्शन उपलब्ध हैं। यह आमतौर पर बुरा हार्डकोडिंग या किसी प्रकार के स्थिर कनेक्शन की ओर जाता है जो हर जगह से हिट हो जाता है।
  • आपकी वस्तुएँ ऑब्जेक्ट की तुलना में SQL जैसी दिखने लगती हैं।
  • ऐप में कुछ भी करना मुश्किल है क्योंकि डेटाबेस बहुत ही खराब है।

इस के शीर्ष पर अन्य बुरे निर्णयों की एक पूरी निहत होने के नाते समाप्त होता है।


2
क्या आप "अन्य बुरे डिजाइन निर्णयों" पर विस्तार से बता सकते हैं?
केविन क्लाइन

2
धन्यवाद। मुझे रूबी के विकास पर रूबी में समस्या होने के लिए इन मुद्दों को नहीं मिला है। व्यवहार और दृढ़ता को अलग से परीक्षण करना अभी भी संभव है। व्यवहार से दृढ़ता को अलग करने वाले IMO का व्यावहारिक मूल्य बहुत कम है।
केविन क्लाइन

@kevin: ये चीजें मिक्सी और बतख टाइपिंग जैसी रूबी सुविधाओं के साथ कमियां हैं। स्थिर भाषाओं के साथ - जैसे C # जो कि ओपी ने अपने प्रश्न में प्रयोग किया है - दोनों को अलग करना थोड़ा अधिक कठिन है।
व्याट बार्नेट

@Wayne: मेरे लिए, कक्षाएं केवल विधियों को लगाने के लिए बक्से हैं - मैं व्यवसाय तर्क को अलग-अलग कक्षाओं में रखकर दृढ़ता से अलग कर सकता हूं, या मैं बस उन्हें यह सुनिश्चित करके वैचारिक रूप से अलग कर सकता हूं कि व्यवसाय के तरीके I / नहीं हैं ओ गरीब प्रतिनिधि समर्थन (उदाहरण के लिए जावा) वाली भाषाओं में, यह बड़ी मात्रा में कोड बचाता है। OTOH, मैं अभी हाइबरनेट हो रहा हूं ताकि मैं पूरी तरह से गलत हो सकूं।
केविन क्लाइन

4
मैं दो चीजें जोड़ूंगा; 1. दृढ़ता तंत्र के साथ युग्मन कोड को कठिन बनाता है, यदि असंभव नहीं है, तो ठीक से इकाई परीक्षण के लिए। 2. सक्रिय रिकॉर्ड एक केंद्रीकृत दृढ़ता तंत्र में रिश्तों के लिए आपके कोड को glues करता है, अगर आप कभी भी निर्णय लेने के लिए अपने मोनोलिथ को विभाजित करना वास्तव में मुश्किल बनाते हैं।
इत्तपनिचुक

15

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

यह भी आम तौर पर आप अपने आप को दोहराने की आवश्यकता है। डीबी से जुड़ने और लेनदेन शुरू करने के लिए अधिकांश दृढ़ता तंत्र में बहुत सारे समान कोड होते हैं। DRY (अपने आप को दोहराएं नहीं) आपको ऐसे तर्क को केंद्रीकृत करने के लिए कोडर के रूप में बताएगा।

यह परमाणु संचालन को भी मुश्किल बना देता है। यदि वस्तुओं का एक समूह सभी या कुछ भी नहीं फैशन में बचाया जाना चाहिए (जैसे एक चालान और इसके चालान के रूप में और / या ग्राहक और / या GL प्रविष्टियों), या तो एक वस्तु को इन सभी अन्य वस्तुओं के बारे में पता होना चाहिए और उनकी दृढ़ता को नियंत्रित करना होगा ( जो नियंत्रित वस्तु के दायरे को बढ़ाता है; बड़े परस्पर रिकॉर्ड आसानी से "भगवान की वस्तुएं" बन सकते हैं जो उनकी निर्भरता के बारे में सब कुछ जानते हैं), या पूरे लेनदेन पर नियंत्रण को डोमेन के बाहर से नियंत्रित किया जाना चाहिए (और उस स्थिति में आप उपयोग क्यों कर रहे हैं) एआर?)

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


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

क्या आप रूबी ActiveRecord उपयोग के उदाहरण प्रदान कर सकते हैं जो आपके बिंदुओं को दर्शाते हैं? मुझे इन समस्याओं का अनुभव नहीं था, लेकिन मेरा आवेदन काफी छोटा था। मैं रूबी में माइग्रेशन लिख सकता था, और उन्हें अलग-अलग डीबी कार्यान्वयन के लिए तैनात कर सकता था। मैंने पाया कि पुनरावृत्ति को दूर करने के लिए रूबी का ActiveRecord बहुत उपयोगी था, इसलिए मैं यह नहीं देखता कि आप यह क्यों बताएंगे कि ActiveRecord का उपयोग करने से विपरीत प्रभाव पड़ेगा। मुझे सहेजने में कोई समस्या नहीं हुई: मैंने ऑब्जेक्ट मॉडल को संशोधित किया, और AR को ऑब्जेक्ट मॉडल को प्रतिबिंबित करने के लिए DB को अपडेट करने दिया।
केविन क्लाइन

2

मूल दोष यह है कि यह आपके डोमेन मॉडल को जटिल बनाता है क्योंकि यह न केवल व्यावसायिक तर्क रखता है बल्कि दृढ़ता की जानकारी भी देता है।

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

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

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

उपयोगकर्ता इकाई के लिए उदाहरण के लिए , UserRepository होगा जो एक ही प्रकार की उपयोगकर्ता वस्तुओं के संग्रह का प्रतिनिधित्व करता है (जो कि उपयोगकर्ता तालिका में संग्रहीत है) जिसे आप ऑपरेशन कर सकते हैं। उपयोगकर्ताओं की तालिका के लिए क्वेरी करने के लिए यह उपयोगकर्ता डेटा मैपर का उपयोग करता है, लेकिन यह डोमेन मॉडल उपयोगकर्ता के लिए अलग हो गया है

रिपॉजिटरी पैटर्न डेटा एक्सेस लेयर का प्रकार है , एक और डेटा एक्सेस ऑब्जेक्ट है केवल अंतर रिपॉजिटरी में एग्रीगेट रूट फीचर है


रिपॉजिटरी और डीएओ पैटर्न अलग-अलग होते हैं, डीएओ सामान्य डेटा एक्सेस है, रिपॉजिटरी सभी एक ही प्रकार की वस्तुओं के संग्रह की दृढ़ता के लिए है। यानी सभी रिपॉजिटरी में एक ही इंटरफ़ेस (जैसे सरणी या सूची) होना चाहिए। अन्य विधियों का राजा रिपॉजिटरी से संबंधित नहीं है । DAO निम्न स्तर है, रिपॉजिटरी DAO का उपयोग कर सकती है। अक्सर, प्रोग्रामर (विशेष रूप से पीएचपी) डीएओ के रूप में रिपॉजिटरी का उपयोग करते हैं, लेकिन यह सही नहीं है।
xmedeko
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.