80

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

संकल्पनात्मक रूप से, मैं एक मॉडल को विचारों और नियंत्रक द्वारा उपयोग किए जाने वाले डेटा के रूप में समझता हूं। इसके अलावा, मॉडल को बनाने के बारे में अलग-अलग विचारों का एक बड़ा सौदा प्रतीत होता है। एक डोमेन मॉडल बनाम, एक ऐप मॉडल बनाम, एक दृश्य मॉडल बनाम, एक सेवा मॉडल बनाम इत्यादि।

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

चलो एक साधारण उदाहरण लें। खाता नियंत्रक जो एमवीसी डिफ़ॉल्ट परियोजना के साथ शामिल है। मैंने कई राय पढ़ी हैं कि खाता कोड शामिल है, खराब डिजाइन का है, एसआरपी का उल्लंघन करता है, आदि .. यदि कोई एमवीसी अनुप्रयोग के लिए "उचित" सदस्यता मॉडल तैयार करना है, तो वह क्या होगा?

मॉडल से एएसपी.NET सेवाओं (सदस्यता प्रदाता, भूमिका प्रदाता, आदि ..) को आप कैसे अलग करेंगे? या आप बिल्कुल?

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

कोई भी इस मुद्दे पर कोई प्रकाश डालने की देखभाल करता है?

+0

"na हाल सवाल मैं भंडार पैटर्न के बारे में पूछा, मैं बिंदु खाली बताया गया था कि भंडार का हिस्सा है मॉडल "अगर मुझे सही याद है तो उत्तरदाता ने अपना जवाब बदल दिया। ये गलत है। – jfar

+0

इसलिए मुझे एक अच्छा शीर्षक के साथ क्यों मुश्किल समय आ रहा था;) –

+1

Thats क्यों आपको चार अलग-अलग प्रश्न पूछना चाहिए। – jfar

उत्तर

65

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

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

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

क्रेडिट कार्ड के साथ काम करते समय बिंदु में मामला है - मुझे भुगतान संसाधित करते समय एक सीवीवी की आवश्यकता होती है, लेकिन मैं सीवीवी स्टोर नहीं कर सकता (यह ऐसा करने के लिए $ 50,000 जुर्माना है)। लेकिन, मैं यह भी चाहता हूं कि आप अपने क्रेडिट कार्ड को संपादित करने में सक्षम हों - पता, नाम या समाप्ति तिथि बदलें। लेकिन आप इसे संपादित करते समय मुझे नंबर या सीवीवी नहीं दे रहे हैं, और मैं निश्चित रूप से पेज पर सादा पाठ में अपना क्रेडिट कार्ड नंबर नहीं डालूंगा। मेरे डोमेन में इन क्रेडिटों को एक नया क्रेडिट कार्ड सहेजने के लिए आवश्यक है क्योंकि आप उन्हें मुझे देते हैं, लेकिन मेरे संपादन मॉडल में कार्ड नंबर या सीवीवी भी शामिल नहीं है।

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

मेरी राय में, नियंत्रक कोड केवल दृश्य पर लक्षित कोड होना चाहिए। इसे दिखाएं, इसे छुपाएं, आदि। सेवा परत को आपके ऐप के लिए व्यवसाय तर्क रखना चाहिए। मुझे यह सब एक ही स्थान पर रखना पसंद है, इसलिए व्यवसाय नियम को बदलना या ट्विक करना आसान है। रिपोजिटरी परत अपेक्षाकृत गूंगा होनी चाहिए - व्यवसाय तर्क से रहित और केवल आपके डेटा से पूछताछ करें और अपनी डोमेन ऑब्जेक्ट्स को वापस कर दें। दृश्य मॉडल को डोमेन मॉडल से अलग करके, कस्टम सत्यापन नियमों की बात आती है जब आपके पास अधिक लचीलापन होता है। इसका मतलब यह भी है कि आपको छिपे हुए क्षेत्रों में डेटा के हर हिस्से को अपने दृश्य में डंप करने की आवश्यकता नहीं है और इसे क्लाइंट और सर्वर (या बैकएंड पर पुनर्निर्माण) के बीच आगे और पीछे धक्का देना है। आपके विचार मॉडल उसके बाद ही जानकारी को देखने के लिए प्रासंगिक घर होगा - और यह या दृश्य तर्क के लिए bools मायने रखता है या enums के लिए जिससे कि दृश्य ही

<% if (!String.IsNullOrEmpty(Model.SomeObject.SomeProperty) && 
    Model.SomeObject.SomeInt == 3 && ...) { %> 
जैसे जटिल तर्क बयान के साथ भरा हुआ नहीं है अनुकूलित किया जा सकता

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

+0

+1 जोश। यह 'लगभग' एक प्रतिकृति है कि हम चीजें कैसे करते हैं। –

+0

हमारे एंटरप्राइज़ एमवीसी एप्लिकेशन में जो कुछ है उसके बारे में सिर्फ एक दर्पण के बारे में। एक एन-टियर वास्तुकला। एमवीसी ऐप केवल एन-टियर क्षेत्रों में व्यावसायिक वस्तुओं और सेवाओं के साथ बातचीत करता है। –

+0

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

16

मैं अक्सर सोचता हूं कि एमवीसी तत्व पारंपरिक वेब अनुप्रयोग संरचना में कैसे फिट होते हैं, जहां आपके पास विचार (पृष्ठ), नियंत्रक, सेवाएं और डेटा ऑब्जेक्ट्स (मॉडल) होते हैं। जैसा कि आपने कहा, इसके कई संस्करण हैं।

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

लेकिन मान लीजिए कि हमारे पास domain driven architecture है, और हमारे डोमेन ऑब्जेक्ट्स जिस तरह से होने की उम्मीद है - दोनों राज्य और व्यापार तर्क हैं। और इस डोमेन पर ही आधारित परिप्रेक्ष्य में चीजों को जगह में आते हैं:

  • दृश्य है यूआई
  • नियंत्रक बटोरता यूआई के आदानों, invokes मॉडल पर विधियों, और यूआई
  • के लिए एक प्रतिक्रिया वापस भेजता है
  • मॉडल हमारे व्यावसायिक घटक हैं - डेटा धारण करना, बल्कि व्यापार तर्क भी।

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

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

+1

+1 जावा डेवलपर की तरह बात की गई ;-) –

+0

उत्कृष्ट बिंदु! एक टिप्पणी: सेवाओं के साथ एक ही गड़बड़ है। कम से कम सेवाएं आवेदन सेवाएं और डोमेन सेवाएं हो सकती हैं। आवेदन सेवा केवल एक पतली आवरण है, जो रेपॉजिटरीज़ आदि से जानकारी एकत्र करती है। डोमेन सेवा व्यावसायिक तर्क प्रदान करती है, जो डोमेन मॉडल के संयोजन का उपयोग कर रही है या सिर्फ सामान जो डोमेन मॉडल में हमेशा फिट नहीं होती है। – Artru

2

एमवीसी पैटर्न और एएसपीनेट फ्रेमवर्क मॉडल के बारे में कोई भेद नहीं करता है।

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

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

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

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

3

मेरी राय में,

मॉडल -

व्यापार तर्क को शामिल नहीं करना चाहिए, यह प्लगेबल (WCF परिदृश्य की तरह) होना चाहिए। इसका उपयोग करने के लिए बाध्य करने के लिए प्रयोग किया जाता है, इसमें गुण होना चाहिए।

व्यापार तर्क -

यह "डोमेन सेवा परत" में रखा जाना चाहिए, यह अलग परत पूरी तरह है। इसके अलावा, "एप्लिकेशन सेवाएं" यहां एक और परत जोड़ देगा।

ऐप सेवाएं व्यापार तर्क लागू करने के लिए डोमेन सेवा परत से बात करती हैं और फिर आखिरकार मॉडल लौटाती हैं।

तो, नियंत्रक, मॉडल और प्रवाह की तरह जाना होगा के लिए अनुप्रयोग सेवा पूछेंगे

Controller->Application Services(using domain services)->Model 
संबंधित मुद्दे