2013-01-10 25 views
7

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

मेरा प्रश्न स्पष्ट है? :) अग्रिम सबसे अच्छा लॉरिन से आपका शुक्रिया अदा

उत्तर

7

तो मुझे रिपोजिटरी विधियों पर अपडेट कहां से कॉल करना चाहिए?

एक टकसाली DDD वास्तुकला में भंडार आम तौर पर एक आवेदन सेवा द्वारा कहा जाता है। एक आवेदन सेवा एक कक्षा है जो आपके डोमेन को encapsulating facade के रूप में कार्य करती है और डोमेन ऑब्जेक्ट्स, रिपॉजिटरीज और अन्य सेवाओं को ऑर्केस्ट्रेट करके डोमेन का उपयोग करता है।

मैं आपके डोमेन से परिचित नहीं हूं, लेकिन मान लीजिए कि एक उपयोग केस है जो एक Quadrant से Field में State को दूसरे स्थान पर ले जाता है। जैसा कि आपने कहा है, Field एआर है। तो अगर आप चाहते हैं एक FieldApplicationService एक संदर्भित FieldRepository:

public class FieldApplicationService 
{ 
    readonly FieldRepository fieldRepository;  

    public void ShiftFieldState(int fieldId, string quadrant, string state) 
    { 
      // retrieve the Field AR 
      var field = this.fieldRepository.Get(fieldId); 
      if (field == null) 
       throw new Exception(); 

      // invoke behavior on the Field AR. 
      field.ShiftState(quadrant, state); 

      // commit changes. 
      this.fieldRepository.Update(field); 
    } 
} 

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

भंडार विभिन्न तरीकों से लागू किया जा सकता है। यह एक ओआरएम जैसे एनएचबीर्नेट के साथ हो सकता है, जिसमें मामले में परिवर्तन ट्रैकिंग का निर्माण किया गया है और सामान्य दृष्टिकोण एक स्पष्ट अद्यतन को कॉल करने के बजाय सभी परिवर्तनों को करना है। NHibernate Unit of Work प्रदान करता है साथ ही कई इकाइयों में परिवर्तनों को एक के रूप में भी किया जा सकता है।

आपके मामले में, जैसा कि आपने कहा है, कोई परिवर्तन ट्रैकिंग नहीं है, इसलिए अपडेट करने के लिए एक स्पष्ट कॉल की आवश्यकता है और यह इसे संभालने के लिए रिपोजिटरी कार्यान्वयन पर निर्भर है। यदि डेटाबेस के रूप में SQL सर्वर का उपयोग करते हैं, तो Update रिपोजिटरी पर विधि Field के सभी गुणों को संग्रहीत प्रक्रिया में भेज सकती है जो आवश्यकतानुसार तालिकाओं को अपडेट करेगी।

+0

प्रश्न: क्या होगा यदि यह स्पष्ट नहीं है कि कौन से योग संशोधित किए गए थे *? जैसेएप्लिकेशन सेवा 'bookLendingService.LendBookToClient (पुस्तक, क्लाइंट)' कॉल करती है। पुस्तक बचाओ? ग्राहक बचाओ? हम कैसे सुनिश्चित कर सकते हैं कि एप्लिकेशन सेवा * जानता है * और यह कभी नहीं बदलेगा? – Timo

+0

मैंने प्रति लेनदेन केवल एक समग्र उत्परिवर्तन के नियम के बारे में सुना है, जो ऊपर दिए गए मेरे प्रश्न का उत्तर हो सकता है। यदि हां, तो इस नियम का कारण क्या है? और एक परिदृश्य से कैसे निपटता है जिसके लिए कई योगों में परिवर्तन की आवश्यकता होती है? – Timo

3

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

public class Field: AggregateRoot 
{ 
    public UpdateField() 
    { 
     // do some business 
     // and trigger FieldUpdatedEvent with necessary parameters 
     .... 
     // you can update some quadrants 
     // and trigger QuadrantsUpdatedEvent with necessary parameters 
    } 
} 

public class FieldEventHandlers: EventHandler 
{ 
    void Handle (FieldUpdatedEvent e) 
    { 
     repository.Update(e.Field); 
    } 
} 

public class QuadrantEventHandlers: EventHandler 
{ 
    void Handle (QuadrantsUpdatedEvent e) 
    { 
     repository.Update(e.Quadrant); 
    } 
} 
+0

आपके उपयोगी उत्तर के लिए धन्यवाद :) – LaurinSt

4

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

एआर को भंडार के बारे में पता नहीं है, यह इसकी चिंता नहीं है। रिपोजिटरी तब सभी एआर दोषों को काम की एक इकाई के रूप में बचाता है (जो सब कुछ या कुछ भी नहीं है)। रेपो यह कैसे करता है, ठीक है, यह इस बात पर निर्भर करता है कि आपने अपनी दृढ़ता रणनीति का निर्धारण कैसे किया।

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

Bu एक बात निश्चित है: किसी डोमेन ऑब्जेक्ट से निपटने पर दृढ़ता के विवरण के बारे में कभी भी विचार न करें। यह एक ओआरएम या कुछ डीबी विशिष्ट सामान के लिए डोमेन जोड़े नहीं है।

+0

आप सभी को धन्यवाद! – LaurinSt

3

"एप्लिकेशन कोड" को भंडार को कॉल करना चाहिए। एप्लिकेशन कोड होस्ट किया जाता है एक आधारभूत संरचना चिंता है। एप्लिकेशन कोड को होस्ट किया जा सकता है, इसके कुछ उदाहरण WCF सेवा, Winforms/WPF अनुप्रयोग के रूप में, या वेब सर्वर पर हैं।

भंडार कार्यान्वयन समग्र रूट और उसके बाल इकाइयों में परिवर्तनों को ट्रैक करने के साथ-साथ उन्हें डीबी में वापस सहेजने के लिए ज़िम्मेदार है।

डोमेन परियोजना

public DomainObject : AggregateRootBase //Implements IAggregateRoot 
{ 
    public void DoSomething() { } 
} 

public IDomainObjectRepository : IRepository<DomainObject>, IEnumerable 
{ 
    DomainObject this[object id] { get; set; } 
    void Add(DomainObject do); 
    void Remove(DomainObject do); 
    int IndexOf(DomainObject do); 
    object IDof(DomainObject do); 
    IEnumerator<DomainObject> GetEnumerator(); 
} 

कार्यान्वयन परियोजना

public SqlDomainObjectRepository : List<DomainObjectDataModel>, IDomainObjectRepository 
{ 
    //TODO: Implement all of the members for IDomainObjectRepository 
} 

आवेदन परियोजना

:

यहाँ एक उदाहरण है

public class MyApp 
{ 
    IDomainObjectRepository repository = //TODO: Initialize a concrete SqlDomainObjectRepository that loads what we need. 
    DomainObject do = repository[0]; //Get the one (or set) that we're working with. 
    do.DoSomething(); //Call some business logic that changes the state of the aggregate root. 
    repository[repository.IDof(do)] = do; //Save the domain object with all changes back to the db. 
} 

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

आशा है कि इससे चीजों को स्पष्ट करने में मदद मिलेगी!

+0

आपके मूल्यवान उत्तर के लिए धन्यवाद :) – LaurinSt

+0

आम तौर पर आपको एक लेनदेन में एक से अधिक कुल संशोधित नहीं करना चाहिए। Http://dddcommunity.org/wp-content/uploads/files/pdf_articles/Vernon_2011_2.pdf देखें। –

+1

यह सामान्य रूप से सच है, लेकिन मुझे यह पसंद है कि आपका लिंक किस प्रकार दस्तावेज़ को 4 अलग-अलग कारण बताता है कि आप इसे ठीक से क्यों करना चाहते हैं। –

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^