एक जटिल डोमेन-केंद्रित अनुप्रयोग में मूल CRUD संचालन के लिए DDD दृष्टिकोण


9

मेरी कंपनी खरोंच से हमारे वेब एप्लिकेशन को फिर से लिख रही है। यह वित्त उद्योग में एक जटिल डोमेन के साथ एक बड़े उद्यम स्तर का अनुप्रयोग है।

हम दृढ़ता के लिए एक ORM (इकाई ढांचे) का उपयोग कर रहे हैं।

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

परतों का उपयोग करते हुए एक DDD दृष्टिकोण में, ऐसा लगता है कि CRUD संचालन डोमेन परत के माध्यम से जाता है। लेकिन कम से कम हमारे मामले में, यह समझ में नहीं आता है।

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

उपयोगकर्ता द्वारा निवेश खाते की स्क्रीन पर "किया गया" क्लिक करने के बाद, और नियंत्रक के लिए एक पोस्ट किया जाता है, नियंत्रक के पास अब निवेश खाते का एक सटीक डेटाबेस प्रतिनिधित्व होता है जिसे उसे बचाने की आवश्यकता होती है। लेकिन किसी कारण से, मुझे नियंत्रक मॉडल को सीधे डेटाबेस मॉडल (एंटिटी फ्रेमवर्क मॉडल) में सीधे मैप करने के बजाय संशोधन करने के लिए डोमेन प्रतिनिधित्व लोड करना चाहिए?

इसलिए संक्षेप में, मैं एक डेटा मॉडल को डोमेन मॉडल के लिए मैप कर रहा हूं, बस इसलिए इसे फिर से डेटा मॉडल पर लगातार बने रहने के लिए मैप किया जा सकता है। उसका क्या अर्थ निकलता है?

जवाबों:


9

ठीक है कि आप अपने खाता निर्माण पृष्ठ को एक EF ऑब्जेक्ट पर सीधे पोस्ट मैपिंग को लागू करने की कल्पना करते हैं जो तब db में सहेजा जाता है।

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

सब कुछ ठीक काम लगता है। लेकिन फिर व्यवसाय एक नया नियम बनाता है।

  • गुरुवार को बनाए गए खातों में 2% बोनस ब्याज दर मिलती है। (मान ब्याज दर खाता क्षेत्रों में से एक है)

अब आपको यह तर्क रखना होगा और आपके पास इसे डालने के लिए एक डोमेन ऑब्जेक्ट नहीं होगा।

DDD मानता है कि आपके पास हमेशा इस तरह के नियम होंगे, और आप शायद करते हैं। एक खाता बनाने के लिए विभिन्न जाँचें होनी चाहिए, एक ऑडिट लॉग इत्यादि, जो केवल 'db को एक पंक्ति लिखने' के लिए नहीं होगा।

अपने डोमेन की योजना यह मानते हुए कि अतिरिक्त तर्क के साथ कोई दृढ़ता या एमवीसी नियंत्रक नहीं है। सुनिश्चित करें कि आप सभी आवश्यकताओं पर कब्जा कर लेते हैं और वे सभी डोमेन मॉडल में हैं।


3
इसे लगाने का यह एक अच्छा तरीका है। मुझे डीबी विवरण के साथ मिश्रित व्यापार नियमों को खोजने से नफरत है। +1
कैंडिड_ऑरेंज

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

मेरे सवालों को उलझा देना। आपको एक पूर्ण उदाहरण देना होगा। यदि आपके पास डोमेन लॉजिक है तो इसे किसी डोमेन ऑब्जेक्ट में जाना चाहिए। इसका मतलब यह नहीं है कि आप दूसरे डोमेन ऑब्जेक्ट को पहले एक से बना सकते हैं
इवान

एक जटिल गणना इंजन की कल्पना करें। गणनाओं को चलाने के लिए जिन इनपुटों की आवश्यकता होती है, उनमें से एक निवेश खाता है, लेकिन सभी निवेश खाता कैल्क इंजन के लिए कुछ समय अवधि में एक आय स्ट्रीम है। एक निवेश खाते का यह डोमेन मॉडल उन कच्चे आदानों से पूरी तरह से अलग है जो उपयोगकर्ता इस निवेश खाते के लिए दर्ज करता है। हालाँकि, जब उपयोगकर्ता नाम, करंट वैल्यू आदि जैसे बुनियादी इनपुट में प्रवेश कर रहा होता है, तब भी सत्यापन तर्क होने की आवश्यकता होती है, लेकिन इसका कैल्क इंजन के उपयोग के मॉडल से कोई लेना-देना नहीं होना चाहिए। तो क्या यहां निवेश खाते के लिए दो डोमेन मॉडल हैं?
wired_in

..... या हो सकता है कि डोमेन में एक निवेश खाता मॉडल
सीआरयूडी

7

उसका क्या अर्थ निकलता है?

संक्षिप्त उत्तर: यह नहीं है

लंबे समय तक उत्तर: एक डोमेन मॉडल विकसित करने के लिए हैवीवेट पैटर्न आपके समाधान के उन हिस्सों पर लागू नहीं होते हैं जो सिर्फ एक डेटाबेस हैं।

उदी दहन का एक दिलचस्प अवलोकन था जो इसे स्पष्ट करने में मदद कर सकता है

दहन का मानना ​​है कि किसी सेवा में किसी प्रकार की कार्यक्षमता और कुछ डेटा दोनों होते हैं। यदि इसके पास डेटा नहीं है, तो यह केवल एक फ़ंक्शन है। यदि यह सब करता है तो डेटा पर CRUD संचालन कर रहा है, तो यह डेटाबेस है।

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

जब आप एक CRUD सिस्टम के साथ काम कर रहे होते हैं, तो आप आमतौर पर डेटा के लिए रिकॉर्ड की प्रणाली नहीं होते हैं। असली दुनिया रिकॉर्ड की पुस्तक है, और अपने डेटाबेस असली दुनिया का सिर्फ एक स्थानीय रूप से कैश प्रतिनिधित्व है।

उदाहरण के लिए, उपयोगकर्ता प्रोफ़ाइल में दिखाई देने वाली अधिकांश जानकारी, जैसे ईमेल पता, या सरकार द्वारा जारी पहचान संख्या, सच्चाई का एक स्रोत है जो आपके व्यवसाय के बाहर रहता है - यह किसी और का मेल व्यवस्थापक है जो ईमेल पते असाइन करता है और रद्द करता है, न कि आपका ऐप। यह सरकार है जो SSNs को असाइन करती है, आपके ऐप को नहीं।

इसलिए आप सामान्य रूप से बाहरी दुनिया से आपके पास आने वाले डेटा पर कोई डोमेन सत्यापन नहीं करने जा रहे हैं; आपके पास यह सुनिश्चित करने के लिए जांच हो सकती है कि डेटा अच्छी तरह से बना है और ठीक से साफ है ; लेकिन यह आपका डेटा नहीं है - आपके डोमेन मॉडल को वीटो नहीं मिलता है।

परतों का उपयोग करते हुए एक DDD दृष्टिकोण में, ऐसा लगता है कि CRUD संचालन डोमेन परत के माध्यम से जाता है। लेकिन कम से कम हमारे मामले में, यह समझ में नहीं आता है।

यह उस मामले के लिए सही है जहां डेटाबेस रिकॉर्ड की पुस्तक है

ऑयरज़ी ने इसे इस तरह से रखा

हालाँकि, बहुत सारी विरासत कोड पर काम करते हुए, मैं सामान्य गलतियों का निरीक्षण करता हूँ कि डोमेन के अंदर क्या है, और बाहर क्या है।

डेटा मॉडल के आसपास कोई व्यावसायिक तर्क न होने पर ही किसी एप्लिकेशन को CRUD माना जा सकता है। यहां तक ​​कि इस (दुर्लभ) मामले में, आपका डेटा मॉडल आपका डोमेन मॉडल नहीं है। इसका मतलब सिर्फ इतना है कि, जैसा कि कोई व्यवसाय लॉजिक्स शामिल नहीं है, हमें इसे प्रबंधित करने के लिए किसी भी अमूर्तता की आवश्यकता नहीं है, और इस प्रकार हमारे पास कोई डोमेन मॉडल नहीं है।

हम डोमेन के अंदर मौजूद डेटा को प्रबंधित करने के लिए डोमेन मॉडल का उपयोग करते हैं; डोमेन के बाहर का डेटा पहले से कहीं और प्रबंधित किया जाता है - हम केवल एक कॉपी कैशिंग कर रहे हैं।

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

तो शायद हमारे यहाँ दो बंधे हुए संदर्भ हैं? एक के लिए एक अलग मॉडल के साथ प्रत्येकinvestment account

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

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

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


वैसे तो सत्यापन और डिफ़ॉल्ट तर्क है, लेकिन यह केवल निवेश खाते के लिए कच्चे आदानों को बनाते / अद्यतन करते समय लागू होता है। तब हम निवेश खाते के लिए एक अधिक समृद्ध मॉडल का उपयोग करते हैं जब हम इसे कैल्क इंजन के इनपुट के रूप में उपयोग करते हैं। तो शायद हमारे यहाँ दो बंधे हुए संदर्भ हैं? एक निवेश खाते के लिए एक अलग मॉडल के साथ प्रत्येक '
wired_in

मैं अभी कई वर्षों के बाद इस पर वापस आया, और आपकी टिप्पणी किसी कारण से अब पहले से अधिक प्रतिध्वनित हो रही है। यहां बहुत सारी अच्छी चीजें हैं, लेकिन क्या आप मेरे लिए एक बात स्पष्ट कर सकते हैं? आपने कहा "डोमेन मॉडल की बात, आखिरकार, यह सुनिश्चित करना है कि डेटा के सभी अपडेट वर्तमान व्यावसायिक हमलावर को बनाए रखें।" यह हमारे ऐप के उस हिस्से पर लागू होगा जो जानकारी को बचाता / अपडेट करता है। अन्य भाग सिर्फ एक गणना इंजन है। यह इनपुट के रूप में डेटा का एक प्रतिनिधित्व लेता है और परिणाम निकालता है। क्या यह डोमेन मॉडल का हिस्सा नहीं है? चूंकि यह संग्रहीत डेटा को प्रभावित नहीं करता है?
वायर्ड_इन

2

आपके डोमेन में आपको यह नहीं जानना चाहिए कि डेटाबेस भी मौजूद है।

आपका डोमेन व्यावसायिक नियमों के बारे में है। जब आपके डेटाबेस को बनाने वाली कंपनी को व्यवसाय से बाहर जाना पड़ता है, तो सामान को बचाना होगा। यही है, यदि आप चाहते हैं कि आपकी कंपनी जीवित रहे। यह वास्तव में अच्छा है जब उन नियमों को परवाह नहीं है कि आपने परिवर्तन किया है कि आप डेटा कैसे बनाए रखते हैं।

डेटाबेस विवरण मौजूद हैं और इससे निपटने की आवश्यकता है। उन्हें कहीं और रहना चाहिए। उन्हें एक सीमा के पार रखो। ध्यान से नियंत्रित करें कि आप उस सीमा पर कैसे संवाद करते हैं या यह सीमा नहीं है।

अंकल बॉब के पास यह कहने के लिए है कि आप अपना डेटा किसमें डाल सकते हैं:

आमतौर पर सीमा पार करने वाला डेटा सरल डेटा संरचनाएं हैं। आप चाहें तो बेसिक स्ट्रक्चर्स या सिंपल डेटा ट्रांसफर ऑब्जेक्ट्स का उपयोग कर सकते हैं। या डेटा केवल फ़ंक्शन कॉल में तर्क हो सकता है। या आप इसे हैशमैप में पैक कर सकते हैं, या इसे किसी ऑब्जेक्ट में बना सकते हैं।

महत्वपूर्ण बात यह है कि सीमाओं के पार पृथक, सरल, डेटा संरचनाएं हैं। हम Entities या डेटाबेस पंक्तियों को धोखा और पारित नहीं करना चाहते हैं। हम नहीं चाहते कि डेटा संरचनाओं में किसी भी प्रकार की निर्भरता हो जो कि निर्भरता नियम का उल्लंघन करती हो।

[…] जब हम एक सीमा के पार डेटा पास करते हैं, तो यह हमेशा उस रूप में होता है जो आंतरिक सर्कल के लिए सबसे सुविधाजनक होता है।

साफ वास्तुकला

वह यह भी बताता है कि आपकी बाहरी परतों को आपकी आंतरिक परतों के लिए प्लग-इन कैसे होना चाहिए ताकि आंतरिक परतों को यह भी पता न चले कि बाहरी परतें मौजूद हैं।

साफ वास्तुकला धोखा शीट

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

यह या तो है या आप तय करते हैं कि आपका डोमेन वास्तव में डेटाबेस में हेरफेर करने के लिए है। उस स्थिति में आपकी डोमेन भाषा SQL है। यदि ठीक है लेकिन दृढ़ता में परिवर्तन से बचने के लिए व्यावसायिक नियमों के आपके कार्यान्वयन की अपेक्षा नहीं है। आप उन्हें पूरी तरह से फिर से लिखने की आवश्यकता समाप्त करेंगे।


हम एक ORM (Entity Framework) का उपयोग कर रहे हैं, इसलिए हमारा डेटाबेस पहले से ही अमूर्त है, लेकिन डेटा मॉडल (Entity फ्रेमवर्क क्लासेस) स्वाभाविक रूप से डेटाबेस तालिकाओं के साथ बहुत अधिक 1 से 1 हैं। समस्या यह है कि हमारे एप्लिकेशन के कुछ हिस्सों में उपयोगकर्ता अनिवार्य रूप से केवल डेटा मॉडल को अपडेट कर रहा है (स्क्रीन सिर्फ टेक्स्ट बॉक्स की एक सूची है जहां प्रत्येक टेक्स्ट बॉक्स डेटाबेस (डेटा मॉडल) में एक फ़ील्ड है।
wired_in

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

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

मैं यह कहने की कोशिश कर रहा हूं कि एक निवेश खाते के लिए उपयोगकर्ता से जो कच्चा डेटा मिलता है, वह यह नहीं है कि हम अपने आवेदन के मुख्य भागों में उस निवेश खाते का प्रतिनिधित्व कैसे करते हैं, जैसे कि जब वह बछड़ों के लिए उपयोग किया जाता है। उदाहरण के लिए, हमारे पास एक बूलियन इनपुट हो सकता है जिसे हम IsManagedAccount नामक डेटाबेस में सहेजते हैं। उपयोगकर्ता संपादन स्क्रीन पर एक रेडियो बटन के माध्यम से हमें इसकी आपूर्ति करता है। ताकि स्क्रीन के नीचे डेटाबेस से प्रतिनिधित्व 1 से 1. है। जब हम अपने डोमेन मॉडल को बाद में आवेदन में बनाते हैं, तो हमारे पास एक प्रबंधित श्रेणी हो सकती है, इस प्रकार कोई बूलियन संपत्ति नहीं होती है। दो संरचनाएं बहुत अलग हैं।
वायर्ड_इन

इसलिए जब उपयोगकर्ता एडिट स्क्रीन पर सिर्फ कच्चे इनपुट्स को एडिट कर रहा होता है, तो मैं डोमेन पिक्चर को क्यों लोड करूंगा और फिर किसी भी तरह से बहुत अधिक जटिलता को जोड़कर मैप किए गए ManagedAccount को एक फ्लैट रिप्रेजेंटेशन में वापस टाइप कर दूंगा जो कि एक मैनचेस्टर के साथ एक सिंगल क्लास है। संपत्ति?
वायर्ड_इन

1

डीडीडी सिद्धांत लागू करना:

उस डोमेन में दो बाउंडेड कॉन्टेक्ट्स हैं:

  • निवेश खाते की गणना। निवेश खाता गणितीय मॉडल एक ऐसा तत्व है जो शायद एक अलग है।
  • कोर फाइनेंस। ग्राहक निवेश खाता इकाईयों में से एक है।

प्रत्येक बंधे हुए संदर्भ में एक अलग वास्तुशिल्प डिजाइन हो सकता है।

उदाहरण:

ग्राहक निवेश खाता एक इकाई (शायद एक अलग, डोमेन पर निर्भर करता है) है और डेटा की दृढ़ता इकाई के भंडार (RDB या OO डेटाबेस की तरह अन्य DB) के माध्यम से बनाई गई है।

CRUD ऑपरेशन के लिए DDD दृष्टिकोण नहीं है। किसी ऑब्जेक्ट के डेटा से बंधे DB क्षेत्र को डिज़ाइन सिद्धांत तोड़ता है।

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