दिलचस्प पोस्ट
संयोजन स्प्रिंग प्रोजेक्ट और जर्सी डिवाइस पर SQLite डेटाबेस का स्थान SSL त्रुटि रूबीगाम्स इंस्टॉल करते समय, 'https://rubygems.org/ से डेटा खींचने में असमर्थ ईवेंट हैंडलर डायनामिक सामग्री पर काम नहीं कर रहा है कगार के डिफॉल्ट घटकों के फ़ोल्डर को कैसे बदला जाए? एक iPhone UITextField को "साफ़ करें" बटन जोड़ना क्या COUNT (*) हमेशा परिणाम निकालते हैं? पायथन पीआईएल के साथ छवि रंग बदलने जीआईटी चेरी-पिक कहते हैं … "38c74d एक मर्ज है, लेकिन कोई एम विकल्प नहीं दिया गया" पैकेज का उपयोग करके विश्व स्तर पर और स्थानीय स्तर पर निर्भरताएं स्थापित करें। Json पायथन के साथ एक UTF8 सीएसवी फ़ाइल पढ़ना Z3: सभी संतोषजनक मॉडल ढूंढना आप एक डाटाटेबल को सामान्य सूची में कैसे परिवर्तित कर सकते हैं? स्ट्रिंग स्थिरांक से 'चार *' के लिए सी ++ नापसंद रूपांतरण अंतर (फ़ंक्शन () {}) (); और फ़ंक्शन () {} ();

डीडीडी – यह नियम है कि संस्थाएं सीधे रिपॉजिटरीज तक नहीं पहुंच सकतीं

डोमेन चालित डिजाइन में, ऐसा लगता है कि संस्थाओं को सीधे रिपॉजिटरीज का उपयोग नहीं करना चाहिए।

क्या यह एरिक इवांस डोमेन चालित डिज़ाइन बुक से आया है, या यह कहीं और से आया है?

इसके पीछे तर्क के लिए कुछ अच्छे स्पष्टीकरण कहां हैं?

संपादित करें: स्पष्ट करने के लिए: मैं व्यावसायिक तर्क से एक अलग परत में डेटा एक्सेस को अलग करने के क्लासिक ओ ओ अभ्यास के बारे में बात नहीं कर रहा हूं – मैं विशिष्ट व्यवस्था के बारे में बात कर रहा हूं जिससे डीडीडी में, संस्थाओं को डेटा से बात नहीं करना है सभी पर पहुंच परत (यानी वे रिपॉजिटरी ऑब्जेक्ट्स के संदर्भ नहीं रखना चाहते हैं)

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

अपडेट: मार्च 2013 में, सवाल पर अपवोट्स का मतलब यह है कि इसमें बहुत रुचि है, और यहां तक ​​कि बहुत सारे उत्तर दिए गए हैं, फिर भी मैं सोचता हूं कि यदि लोगों के बारे में इस बारे में कोई विचार है तो इसके लिए अधिक जगह है।

वेब के समाधान से एकत्रित समाधान "डीडीडी – यह नियम है कि संस्थाएं सीधे रिपॉजिटरीज तक नहीं पहुंच सकतीं"

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

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

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

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

टिप्पणी 1 के उत्तर : सही, अच्छा सवाल इसलिए डोमेन परत में सभी मान्यता नहीं होती है तीव्र में एक विशेषता है "डोमेन साझेदारी" जो कि आप क्या चाहते हैं यह दृढ़ता से जागरूक है, लेकिन एक विशेषता होने पर डोमेन परत को साफ रहता है। यह सुनिश्चित करता है कि आपके पास डुप्लिकेट इकाई नहीं है, आपके उदाहरण में समान नाम।

लेकिन हम और अधिक जटिल सत्यापन नियमों के बारे में बात करते हैं। मान लें कि आप Amazon.com हैं क्या आपने कभी समाप्त हो चुके क्रेडिट कार्ड के साथ कुछ का आदेश दिया है? मेरे पास, जहां मैंने कार्ड अपडेट नहीं किया है और कुछ खरीदा है। यह ऑर्डर स्वीकार करता है और यूआई मुझे सूचित करता है कि सब कुछ पीच है लगभग 15 मिनट बाद, मुझे एक ई-मेल मिलेगा कि मेरे आदेश के साथ समस्या है, मेरा क्रेडिट कार्ड अमान्य है यहाँ क्या हो रहा है यह है कि, आदर्श रूप में, डोमेन परत में कुछ regex सत्यापन है। क्या यह सही क्रेडिट कार्ड नंबर है? यदि हां, तो आदेश जारी रहें हालांकि, एप्लिकेशन कार्य परत पर अतिरिक्त सत्यापन किया जाता है, जहां एक बाहरी सेवा को यह देखने के लिए कहा जाता है कि भुगतान क्रेडिट कार्ड पर किया जा सकता है या नहीं। यदि नहीं, तो वास्तव में कुछ भी जहाज नहीं, आदेश निलंबित और ग्राहक की प्रतीक्षा करें। यह सब एक सेवा स्तर में होना चाहिए।

सेवा स्तर पर सत्यापन ऑब्जेक्ट बनाने से डरो मत, जो कि रिपॉजिटरी तक पहुंच सकते हैं। बस इसे डोमेन परत से बाहर रखें

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

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

जैसा कि आप देख सकते हैं कि ए इकाई ए बी बी के जीवन चक्र में अधिक शामिल हो सकती है और यह मॉडल को अधिक जटिलता जोड़ सकता है।

मुझे लगता है कि (बिना किसी उदाहरण के) यूनिट-परीक्षण अधिक जटिल होगा

लेकिन मुझे यकीन है कि ऐसी परिस्थितियां हमेशा मौजूद रहेंगी जहां आप संस्थाओं के माध्यम से रिपॉजिटरी का उपयोग करने के लिए परीक्षा लेते हैं। आपको एक वैध फैसले करने के लिए प्रत्येक परिदृश्य को देखना होगा। फायदा और नुकसान। लेकिन मेरी राय में रिपॉजिटरी-इकाई समाधान विपक्ष का एक बहुत से शुरू होता है। यह पेशेवरों के साथ एक बहुत खास परिदृश्य होना चाहिए जो विपक्ष को संतुलन देता है ….

सबसे पहले, मैं अपनी कुछ संस्थाओं को खजाने तक पहुंचने की अनुमति देने के लिए अनुनय का था (यानी ओआरएम के बिना आलसी लोडिंग)। बाद में मैं निष्कर्ष पर आया कि मुझे नहीं चाहिए और मुझे वैकल्पिक तरीकों से मिलना चाहिए:

  1. हमें अपने इरादों को एक अनुरोध में और डोमेन से क्या चाहिए, इसलिए हम समग्र व्यवहार के निर्माण या लागू करने से पहले रिपॉजिटरी कॉल कर सकते हैं। यह असंगत इन-मेमोरी स्टेट की समस्या और आलसी लोड करने की आवश्यकता से बचने में भी सहायता करता है (यह आलेख देखें )। गंध यह है कि आप डेटा एक्सेस के बारे में चिंता किए बिना अब अपनी इकाई की स्मृति आवृत्ति नहीं बना सकते हैं
  2. सीक्यूएस (कमांड क्वायर सेपरेशन) हमारी संस्थाओं में चीजों के लिए रिपॉजिटरी कॉल करने की आवश्यकता को कम करने में मदद कर सकता है।
  3. हम एक विनिर्देश का उपयोग डोमेन लॉजिक जरूरतों को पढ़ाने और संवाद करने के लिए कर सकते हैं और इसके बदले रिपॉजिटरी को पास कर सकते हैं (एक सेवा हमारे लिए इन चीजों को आर्केस्ट कर सकती है)। विनिर्देश उस इकाई से आ सकता है जो कि अपरिवर्तनीय बनाए रखने के प्रभारी है। रिपॉजिटरी विनिर्देशन के हिस्सों की अपनी क्वेरी कार्यान्वयन में व्याख्या करेगा और क्वेरी परिणामों पर विनिर्देशन से नियम लागू करेगा। इसका उद्देश्य डोमेन परत में डोमेन तर्क रखना है। यह सर्वव्यापी भाषा और संचार बेहतर कार्य करता है। कल्पना कीजिए कि "अतिदेय आदेश विनिर्देश" बनाम "tbl_order से फ़िल्टर ऑर्डर, जहां रखा_ट sysdate से 30 मिनट से कम है" (यह उत्तर देखें)।
  4. एकल-जिम्मेदारी सिद्धांत का उल्लंघन होने के बाद से संस्थाओं के व्यवहार के बारे में तर्क अधिक कठिन हो जाता है। यदि आपको भंडारण / दृढ़ता के मुद्दों को जानने की ज़रूरत है, जहां आपको जाना है और कहां जाना नहीं है
  5. यह वैश्विक राज्य (रिपॉजिटरी और डोमेन सेवाओं के माध्यम से) को एक इकाई द्वि-दिशात्मक पहुंच देने के खतरे से बचा जाता है। आप अपनी लेनदेन सीमा को भी तोड़ना नहीं चाहते हैं

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

अंगूठे के एक नियम के रूप में, अगर हम संभवतः संभवतः रिपॉजिटरी (12) के अंदर समुच्चय के इस्तेमाल से बचने का प्रयास करें,

वर्नोन, वॉन (2013-02-06)। डोमेन-प्रेरित डिजाइन (जलाने स्थान 6089) को कार्यान्वित करना पियर्सन एजुकेशन किंडल संस्करण।

और समूह के अध्याय 10 में, "मॉडल नेविगेशन" शीर्षक वाले अनुभाग में, वे कहते हैं (वे अन्य कुल जड़ों को संदर्भित करने के लिए वैश्विक अद्वितीय आईडी के इस्तेमाल की सिफारिश करने के बाद):

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

वह कोड में इस का एक उदाहरण दिखाता है:

public class ProductBacklogItemService ... { ... @Transactional public void assignTeamMemberToTask( String aTenantId, String aBacklogItemId, String aTaskId, String aTeamMemberId) { BacklogItem backlogItem = backlogItemRepository.backlogItemOfId( new TenantId( aTenantId), new BacklogItemId( aBacklogItemId)); Team ofTeam = teamRepository.teamOfId( backlogItem.tenantId(), backlogItem.teamId()); backlogItem.assignTeamMemberToTask( new TeamMemberId( aTeamMemberId), ofTeam, new TaskId( aTaskId)); } ... } 

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

मैं तब हमेशा मार्को पिवेटा @ ओकेरामियस के साथ कुछ चर्चा कर रहा था, जिसने मुझे डोमेन से एक विनिर्देशन खींचने और उस का उपयोग करने पर थोड़ा सा कोड दिखाया था:

1) यह अनुशंसित नहीं है:

 $user->mountFriends(); // <-- has a repository call inside that loads friends? 

2) एक डोमेन सेवा में, यह अच्छा है:

 public function mountYourFriends(MountFriendsCommand $mount) { /* see http://store.steampowered.com/app/296470/ */ $user = $this->users->get($mount->userId()); $friends = $this->users->findBySpecification($user->getFriendsSpecification()); array_map([$user, 'mount'], $friends); } 

मैंने इस ब्लॉग को इकाईयों के अंदर रिपॉजिटरी के समक्ष ध्वस्त करने के लिए काफी अच्छा तर्क दिया है:

http://thinkbeforecoding.com/post/2009/03/04/How-not-to-inject-services-in-entities

डेटा एक्सेस अलग क्यों है?

किताब से, मुझे लगता है कि अध्याय मॉडल प्रेरित डिजाइन के पहले दो पृष्ठों से यह तर्क मिलता है कि आप डोमेन मॉडल के कार्यान्वयन से तकनीकी कार्यान्वयन के विवरण को क्यों समझा सकते हैं।

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

ऐसा लगता है कि एक अलग "विश्लेषण मॉडल" से बचने के उद्देश्य से जो सिस्टम के वास्तविक क्रियान्वयन से तलाक हो जाता है।

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

दूसरे दिशा में, डोमेन मॉडल में बहुत अधिक तकनीकी चिंताओं को पेश करने वाले डेवलपर्स इस विभाजन को भी ठीक कर सकते हैं।

तो आप इस बात पर विचार कर सकते हैं कि दृढ़ता जैसे चिंताओं को अलग करने के अभ्यास से इन डिजाइनों के खिलाफ सुरक्षा के लिए एक विश्लेषण मॉडल विचलन हो सकता है। यदि मॉडल में दृढ़ता जैसी चीजों को पेश करने के लिए आवश्यक लगता है तो यह एक लाल झंडा है शायद मॉडल कार्यान्वयन के लिए व्यावहारिक नहीं है

का हवाला देते हुए:

"एक मॉडल में त्रुटि की संभावना कम हो जाती है, क्योंकि डिज़ाइन अब सावधानी से विचार किए जाने वाले मॉडल का प्रत्यक्ष परिणाम है। डिजाइन, और यहां तक ​​कि कोड में भी, एक मॉडल की संचार क्षमता है।"

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

यदि एक डेटाबेस को एक्सेस करने की आवश्यकता विशिष्टता की जाँच जैसी चीज़ों के लिए है, तो इस पर एक नज़र डालें:

उडी दहन: डीडीडी लागू करते समय सबसे बड़ी गलतियां टीम बनाते हैं

http://gojko.net/2010/06/11/udi-dahan-the-biggest-mistakes-teams-make-when-applying-ddd/

"सभी नियम समान नहीं बनाए गए हैं"

तथा

डोमेन मॉडल पैटर्न का कामकाज

http://msdn.microsoft.com/en-us/magazine/ee236415.aspx#id0400119

"डोमेन मॉडल का उपयोग न करने के लिए परिदृश्य" के तहत, जो एक ही विषय पर छूता है।

डेटा पहुंच को अलग कैसे करें

एक अंतरफलक के माध्यम से डेटा लोड करना

"डेटा एक्सेस परत" को एक इंटरफ़ेस के माध्यम से समझाया गया है, जिसे आप आवश्यक डेटा प्राप्त करने के लिए कॉल करते हैं:

 var orderLines = OrderRepository.GetOrderLines(orderId); foreach (var line in orderLines) { total += line.Price; } 

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

विपक्षः कॉलिंग कोड को मानना ​​चाहिए कि क्या लोड किया गया है और क्या नहीं है।

कहो GetOrderLines प्रदर्शन कारणों के लिए एक रिक्त ProductInfo संपत्ति के साथ OrderLine ऑब्जेक्ट्स रिटर्न। डेवलपर को अंतरफलक के पीछे कोड का अंतरंग ज्ञान होना चाहिए।

मैंने वास्तविक पद्धति पर इस विधि की कोशिश की है आप प्रदर्शन समस्याओं को ठीक करने के प्रयास में हर बार लोड किए जाने के दायरे को बदलते हैं। यह देखने के लिए कि क्या है और लोड नहीं किया जा रहा है, आप डेटा एक्सेस कोड को देखने के लिए इंटरफ़ेस के पीछे देखना चाहते हैं।

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

निष्कर्ष: काफी कम जुदाई!

धीरे लोड हो रहा है

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

 foreach (var line in order.OrderLines) { total += line.Price; } 

पेशेवरों: 'WHEN, WHERE, और HOW' डेटा एक्सेस का डोमेन लॉजिक पर ध्यान केंद्रित डेवलपर से छिपा हुआ है। कुल डेटा में कोई कोड नहीं है जो लोडिंग डेटा से संबंधित है। लोड किए गए डेटा की मात्रा कोड द्वारा आवश्यक सटीक राशि हो सकती है।

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

भूमिका अंतरफलक / उत्सुक प्राप्ति

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

लाइकिंग रणनीति इस तरह दिख सकती है:

 public class BillOrderFetchingStrategy : ILoadDataFor<IBillOrder, Order> { Order Load(string aggregateId) { var order = new Order(); order.Data = GetOrderLinesWithPrice(aggregateId); return order; } } 

फिर आपका कुल मिलाकर दिख सकता है:

 public class Order : IBillOrder { void BillOrder(BillOrderCommand command) { foreach (var line in this.Data.OrderLines) { total += line.Price; } etc... } } 

बिलऑर्डर फ़ेटिविंग स्ट्रेटजी का उपयोग कुल मिलाकर बनाने के लिए किया जाता है, और फिर कुल मिलाकर इसका काम करता है

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

विपक्ष: डोमेन कोड बदलने के बाद डेवलपर को फिर से आकर्षित करने की रणनीति को समायोजित / समीक्षा करना होगा

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

क्या एक उत्कृष्ट सवाल मैं खोज के एक ही रास्ते पर हूं, और इंटरनेट भर में अधिकांश उत्तर कई समस्याओं को लेकर आते हैं क्योंकि वे समाधान लाते हैं

तो (कुछ लिखने के जोखिम पर कि मैं अब से एक वर्ष से असहमत हूं) यहां तक ​​कि मेरी खोज इतनी दूर है।

सबसे पहले, हम एक समृद्ध डोमेन मॉडल पसंद करते हैं , जो हमें उच्च खोज योग्यता प्रदान करता है (हम सभी के साथ क्या कर सकते हैं) और पठनीयता (अभिव्यक्ति विधि कॉल)।

 // Entity public class Invoice { ... public void SetStatus(StatusCode statusCode, DateTime dateTime) { ... } public void CreateCreditNote(decimal amount) { ... } ... } 

हम किसी संस्था के कन्स्ट्रक्टर में किसी भी सेवा को इंजेक्शन लगाने के बिना इसे प्राप्त करना चाहते हैं, क्योंकि:

  • एक नया व्यवहार (जो एक नई सेवा का उपयोग करता है) का परिचय एक कन्स्ट्रक्टर बदलाव का कारण बन सकता है, जिसका अर्थ है कि परिवर्तन हर इकाई को प्रभावित करता है जो इकाई को इन्स्तांत करता है !
  • ये सेवाएं मॉडल का हिस्सा नहीं हैं , लेकिन निर्माता-इंजेक्शन यह सुझाएगा कि वे थे।
  • अक्सर एक सेवा (यहां तक ​​कि इसके इंटरफ़ेस) डोमेन के हिस्से के बजाय एक कार्यान्वयन विवरण है। डोमेन मॉडल में एक बाहरी-निर्भर निर्भरता होगी
  • यह भ्रामक हो सकता है कि इकाई इन निर्भरताओं के बिना क्यों मौजूद नहीं हो सकती। (क्रेडिट नोट सेवा, आप कहते हैं? मैं क्रेडिट नोट्स के साथ कुछ भी नहीं कर रहा हूं …)
  • यह कठिन प्रयास करना होगा, इस प्रकार परीक्षण करना कठिन होगा
  • यह समस्या आसानी से फैलती है, क्योंकि इसमें से अन्य इकाइयां एक ही निर्भरता प्राप्त होती हैं – जो उन पर बहुत अप्राकृतिक निर्भरता की तरह दिख सकती हैं।

तो, हम यह कैसे कर सकते हैं? मेरा निष्कर्ष अभी तक है कि विधि निर्भरताएं और दोहरी प्रेषण एक सभ्य समाधान प्रदान करते हैं।

 public class Invoice { ... // Simple method injection public void SetStatus(IInvoiceLogger logger, StatusCode statusCode, DateTime dateTime) { ... } // Double dispatch public void CreateCreditNote(ICreditNoteService creditNoteService, decimal amount) { creditNoteService.CreateCreditNote(this, amount); } ... } 

CreateCreditNote() अब क्रेडिट नोट्स बनाने के लिए जिम्मेदार एक सेवा की आवश्यकता है यह Invoice इकाई से खोज Invoice बनाए रखते हुए, दोहरी प्रेषण का उपयोग करता है, पूरी तरह से जिम्मेदार सेवा के लिए काम को ऑफलोड करता है

SetStatus() अब एक लकड़हारा पर एक साधारण निर्भरता है , जो स्पष्ट रूप से काम का हिस्सा प्रदर्शन करेंगे

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

हम अभी भी पैरामीटर 'लकड़हारा' का नाम दे सकते हैं, जिसमें हमारी मंशा प्रकट करने की उम्मीद है। थोड़ा कमजोर लगता है, हालांकि।

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

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

 public class Invoice { public IEnumerable<CreditNote> GetCreditNotes(ICreditNoteRepository repository) { ... } } 

वास्तव में, यह कभी परेशानी आलसी भार के लिए एक विकल्प प्रदान करता है । हम Invoice को केवल उस क्रेडिट नोट को याद रख सकते हैं जो उसने लोड किए हैं, और पुनः लोड करने से बचें।

सच्चाई के लिए, संपत्ति आधारित आलसी भार, मैं वर्तमान में कन्स्ट्रक्टर इंजेक्शन का उपयोग करता हूं, लेकिन एक दृढ़ता-अज्ञानी तरीके से

 public class Invoice { // Lazy could use an interface (for contravariance if nothing else), but I digress public Lazy<IEnumerable<CreditNote>> CreditNotes { get; } // Give me something that will provide my credit notes public Invoice(Func<Invoice, IEnumerable<CreditNote>> lazyCreditNotes) { this.CreditNotes = new Lazy<IEnumerable<CreditNotes>>() => lazyCreditNotes(this)); } } 

एक तरफ, एक रिपॉजिटरी जो डेटाबेस से Invoice को लोड करता है, उस फ़ंक्शन पर निःशुल्क पहुंच हो सकती है जो संबंधित क्रेडिट नोट लोड करेगा, और उस फ़ंक्शन को Invoice में Invoice

दूसरी तरफ, कोड जो वास्तविक वास्तविक Invoice बनाता है, वह केवल एक फ़ंक्शन देता है जो एक खाली सूची देता है:

 new Invoice(inv => new List<CreditNote>() as IEnumerable<CreditNote>) 

(एक कस्टम ILazy<out T> हमें बदसूरत कलाकारों से IEnumerable छुटकारा दे सकता है, लेकिन यह चर्चा को मुश्किल करेगा।)

आपकी राय, वरीयताओं और सुधारों को सुनकर मुझे खुशी होगी!

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

जिन कारणों के बारे में मैं सोच सकता हूं:

  • चिंताओं का पृथक्करण (संस्थाओं को जिस तरह से जारी रखा गया है, उससे अलग होना चाहिए क्योंकि उपयोग की परिदृश्य के आधार पर एक ही इकाई का अस्तित्व निरंतर किया जा सकता है)
  • तार्किक रूप से, संस्थाओं को स्तर के नीचे एक स्तर में देखा जा सकता है जिसमें रिपॉजिटरी कार्य करते हैं। निम्न स्तर के घटकों को उच्च स्तर घटकों पर ज्ञान नहीं होना चाहिए। इसलिए प्रविष्टियों को रिपॉजिटरीज पर ज्ञान नहीं होना चाहिए।

मैं यह ऑब्जेक्ट ओरिएंटेड प्रोग्राम्स को सीखा, इससे पहले कि यह सब अलग-अलग परत चर्चा दिखाई दे, और मेरी पहली ऑब्जेक्ट्स / क्लासेस सीधे डेटाबेस पर नक्शा करें।

अंततः, मैंने एक इंटरमीडिएट लेयर जोड़ा क्योंकि मुझे किसी अन्य डेटाबेस सर्वर पर माइग्रेट करना पड़ा। मैंने एक ही परिदृश्य के बारे में कई बार देखा / सुना है

मुझे लगता है कि आपके व्यावसायिक तर्क से डेटा एक्सेस (उर्फ "रिपॉज़िटरी") को अलग करना, उन चीज़ों में से एक है, जिन्हें कई बार पुन: स्थापित किया गया है, डोमेन डूवर डिज़ाइन बुक में ऐलट किया गया, यह बहुत "शोर" बना रहा है

मैं वर्तमान में 3 परतों (जीयूआई, लॉजिक, डेटा एक्सेस) का उपयोग करता हूं, जैसे कि कई डेवलपर करता है, क्योंकि इसकी एक अच्छी तकनीक है

डेटा को अलग करना, एक Repository लेयर (उर्फ Data Access लेयर) में, एक अच्छा प्रोग्रामिंग तकनीक की तरह देखा जा सकता है, न कि सिर्फ एक नियम, जैसा कि अनुसरण करना है।

कई तरीकों की तरह, आप शुरू कर सकते हैं, लागू नहीं कर सकते हैं, और अंत में, अपने प्रोग्राम को अपडेट कर सकते हैं, एक बार जब आप उन्हें समझते हैं।

उद्धरण: इलियड का पूरी तरह से होमर द्वारा आविष्कार नहीं किया गया था, कार्मिना बुराना पूरी तरह से कार्ल ऑरफ द्वारा आविष्कार नहीं किया गया था, और दोनों ही मामलों में, वह व्यक्ति जिसने दूसरों को काम पर रखा है, सब कुछ, क्रेडिट प्राप्त किया 😉

क्या यह एरिक इवांस डोमेन प्रेरित डिजाइन किताब से आया था, या यह कहीं और से आया था?

यह पुरानी सामान है एरिक की पुस्तक ने इसे थोड़ा और अधिक चर्चा की।

इसके पीछे तर्क के लिए कुछ अच्छे स्पष्टीकरण कहां हैं?

कारण सरल है – मानव मन कमजोर हो जाता है जब यह अस्पष्ट संबंधित कई संदर्भों का सामना करता है। वे अस्पष्टता (दक्षिण / उत्तरी अमेरिका में अमेरिका दक्षिण / उत्तरी अमेरिका का अर्थ है) का कारण बनता है, अस्पष्टता की जानकारी के निरंतर मानचित्रण की ओर जाता है, जब भी मन "इसे छूता है" और यह खराब उत्पादकता और त्रुटियों के रूप में बताता है

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

सादृश्य में: यदि आप हस्तलिखित करने के लिए सीख रहे हैं, आपको समझना चाहिए कि कलम कहाँ बना है, क्यों स्याही कागज पर रखती है, जब कागज का आविष्कार हुआ और अन्य प्रसिद्ध चीनी आविष्कार क्या हैं।

संपादित करें: स्पष्ट करने के लिए: मैं व्यावसायिक तर्क से एक अलग परत में डेटा एक्सेस को अलग करने के क्लासिक ओ ओ अभ्यास के बारे में बात नहीं कर रहा हूं – मैं विशिष्ट व्यवस्था के बारे में बात कर रहा हूं जिससे डीडीडी में, संस्थाओं को डेटा से बात नहीं करना है सभी पर पहुंच परत (यानी वे रिपॉजिटरी ऑब्जेक्ट्स के संदर्भ नहीं रखना चाहते हैं)

कारण अभी भी वही है जो मैंने ऊपर वर्णित किया है। यहाँ यह सिर्फ एक कदम आगे है अगर संस्थाओं को आंशिक रूप से अज्ञान रहना चाहिए तो वे पूरी तरह से (कम से कम करीब) हो सकते हैं? कम डोमेन-संबंधी असंबंधित चिंताएं हमारे मॉडल में हैं – अधिक सांस लेने का कमरा हमारे दिमाग में आता है जब उसे पुन: व्याख्या करना होता है।

बस वेरनॉन वॉन एक समाधान देता है:

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

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