2010-04-16 16 views
5

में एप्लिकेशन परतों को परिभाषित करना मेरे पास डीडीडी के बारे में एक प्रश्न है। मैं डीडीडी सीखने के लिए एक आवेदन बना रहा हूं और मेरे पास लेयरिंग के बारे में एक सवाल है। मुझे लगता है कि इस तरह से काम करता है एक आवेदन है: -> डोमेन परत -डोमेन-संचालित-डिजाइन

यूआई परत कॉल => आवेदन परत> डाटाबेस

यहाँ कैसे कोड लग रहा है की एक छोटा सा उदाहरण है:

//****************UI LAYER************************ 
//Uses Ioc to get the service from the factory. 
//This factory would be in the MyApp.Infrastructure.dll 
IImplementationFactory factory = new ImplementationFactory(); 

//Interface and implementation for Shopping Cart service would be in MyApp.ApplicationLayer.dll 
    IShoppingCartService service = factory.GetImplementationFactory<IShoppingCartService>(); 

    //This is the UI layer, 
    //Calling into Application Layer 
    //to get the shopping cart for a user. 

    //Interface for IShoppingCart would be in MyApp.ApplicationLayer.dll 
    //and implementation for IShoppingCart would be in MyApp.Model. 
    IShoppingCart shoppingCart = service.GetShoppingCartByUserName(userName); 

    //Show shopping cart information. 
    //For example, items bought, price, taxes..etc 
    ... 

    //Pressed Purchase button, so even for when 
    //button is pressed. 
    //Uses Ioc to get the service from the factory again. 
    IImplementationFactory factory = new ImplementationFactory(); 
    IShoppingCartService service = factory.GetImplementationFactory<IShoppingCartService>(); 
    service.Purchase(shoppingCart); 


    //**********************Application Layer********************** 
    public class ShoppingCartService : IShoppingCartService 
    { 
     public IShoppingCart GetShoppingCartByUserName(string userName) 
     { 
      //Uses Ioc to get the service from the factory. 
      //This factory would be in the MyApp.Infrastructure.dll 
      IImplementationFactory factory = new ImplementationFactory(); 

      //Interface for repository would be in MyApp.Infrastructure.dll 
      //but implementation would by in MyApp.Model.dll 
      IShoppingCartRepository repository = factory.GetImplementationFactory<IShoppingCartRepository>(); 

      IShoppingCart shoppingCart = repository.GetShoppingCartByUserName(username); 
      //Do shopping cart logic like calculating taxes and stuff 
      //I would put these in services but not sure? 
      ... 

      return shoppingCart; 
     } 

     public void Purchase(IShoppingCart shoppingCart) 
     { 
      //Do Purchase logic and calling out to repository 
      ... 
     } 
    } 

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

धन्यवाद!

+0

मेरे लिए अच्छा लग रहा है !!! –

उत्तर

2

डीडीडी सर्वोत्तम काम करता है जब सेवाएं (एप्लिकेशन लेयर) डोमेन ऑब्जेक्ट्स पर केवल कमांड का पर्दाफाश करती है, ऑब्जेक्ट्स स्वयं नहीं।

आप उदाहरण में मैं खरीद की तरह एक सेवा विधि बनाना होगा जो आंतरिक रूप से भंडार से एक ShoppingCart मिलेगा (productName, पूर्णांक मात्रा strng) एक उत्पाद (जैसा कि इसके नाम से) मिलता है (यहाँ इंटरफेस का उपयोग करने की जरूरत नहीं है) रिपोजिटरी से और कार्ट को कॉल करें। AddProduct (उत्पाद, मात्रा)

नहीं, कार्ट में उत्पादों को जोड़ने का व्यवसाय तर्क, कुल राशि, कुल वजन या अन्य व्यावसायिक सामान की गणना मोड में encapsulated है।

+0

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

+1

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

3

जब आप

पूछना अपने मॉडल मेरे डोमेन मॉडल निकलना चाहिए?

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

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

IShoppingCart shoppingCart = repository.GetShoppingCartByUserName(username); 
//Do shopping cart logic like calculating taxes and stuff 
//I would put these in services but not sure? 

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

1

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

  • सेवा कॉल Manager.GetSomething()
  • प्रबंधक, विभिन्न खजाने से डेटा प्राप्त व्यापार तर्क करते हैं और वापस जाने के परिणाम
  • मैनेजर वापसी परिणाम लेकिन डोमेन वस्तुओं लौट ही कभी नहीं! यदि आपके पास उपयोगकर्ता नामक डोमेन ऑब्जेक्ट है, तो आपको नामकरण सम्मेलन के साथ चिपकना चाहिए, जिसे आपने आविष्कार किया है और उपयोगकर्ता को डेटाडेटा कंट्रैक्ट या इसी तरह से मैप करें। डोमेन ऑब्जेक्ट्स का पर्दाफाश न करें। यह अतिरिक्त काम है लेकिन आपको यूआई के साथ अपना डोमेन मॉडल नहीं जोड़ना चाहिए।
  • कई बार डोमेन वस्तु तरीकों है अपने प्रश्न के बारे में कुछ व्यापार तर्क
+2

क्या आप इस बारे में विशिष्ट हो सकते हैं कि आपके द्वारा संदर्भित एरिक इवांस की सिफारिश कहां से आई थी? मुझे अपनी पुस्तक में ऐसा कुछ याद नहीं है (मुझे कुछ याद आया होगा, जाहिर है)। –

+0

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

+2

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

0

करना है:

"मैं और सेवाओं में बजाय मेरे व्यापार नियमों के सबसे डाल करने के लिए मॉडल लग गए हैं मुझे यकीन नहीं है कि यह सही है या नहीं? "

यदि कोई व्यवसाय नियम, अन्य संसाधनों (डेटाबेस, सेवाओं, डोमेन ऑब्जेक्ट्स) तक नहीं पहुंचता है, तो आप डोमेन ऑब्जेक्ट में नियम बना सकते हैं। यदि यह अन्य संसाधनों तक पहुंचता है तो आपको उन्हें डोमेन सेवाओं में रखना चाहिए।