2010-01-19 8 views
5

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

भंडार करने के लिए एक आदेश को जोड़ने के लिए, मैं आमतौर पर लोगों को ईद के बिना आदेश का दृष्टांत और फिर भंडार वस्तु पूरा हो देखें:

class OrderRepository 
{ 
    void Add(Order order) 
    { 
     // Insert order into db and populate Id of new order 
    } 
} 

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

class OrderRepository 
{ 
    Order AddOrder(Customer customer) 
     // It might be better to call this CreateOrder 
    { 
     // Insert record into db and return a new instance of Order 
    } 
} 

क्या मैं इस दृष्टिकोण के बारे में की तरह है कि एक आदेश एक आईडी के बिना अपरिभाषित है:

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

किसी भी तरह से काम करता है, इसलिए मेरा सवाल है: क्या मुझे इन दो व्याख्याओं में से एक के साथ रहना है, या क्या सम्मिलन मॉडल का सर्वोत्तम अभ्यास है?

मुझे यह उत्तर मिला जो समान है, लेकिन मूल्य वस्तुओं के लिए: how should i add an object into a collection maintained by aggregate root। जब किसी मूल्य वस्तु की बात आती है तो कोई भ्रम नहीं होता है, लेकिन मेरा प्रश्न बाहरी स्रोत (ऑटो-जेनरेटेड डाटाबेस आईडी) से प्राप्त पहचान वाले इकाई से संबंधित है।

+0

मैं तर्क देता हूं कि एक आईडी के बिना एक ऑर्डर एक ऑर्डर इकाई नहीं है, जहां आपका पहला प्रारंभिक विचार आता है। इसका मुकाबला करने के लिए, आपको अपनी वस्तुओं की स्थिति याद रखना होगा। समय पर एक विराम के रूप में 'राज्य' को देखो। यानी, एक वेबपेज अनुरोध। आदेश के निर्माण के दौरान, हाँ, इसमें पहले कोई आईडी नहीं है लेकिन आप अभी तक इसके राज्य के साथ नहीं किए गए हैं - आप इसे() में भंडार में जोड़ते हैं, जिससे ऑर्डर() की निरंतर स्थिति को पूरा किया जाता है, जो अब है पूर्ण। – eduncan911

+0

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

+0

पहचान उतनी ही कट और सूखी नहीं है जितनी आप सोचेंगे। मेरी आस्था में, हमारी पहचान हमारी धारणा से मौजूद हमारी अनोखी आत्माएं हैं। लेकिन सरकार के लिए, हमारी पहचान एक से अधिक माध्यमों के माध्यम से स्थापित की जा सकती है: जन्म प्रमाण पत्र, पासपोर्ट, आदि। ऐसे समय में एक बिंदु है जहां बच्चे को सरकार के लिए कोई आधिकारिक पहचान नहीं है लेकिन सरकार अभी भी इसे एक इकाई के रूप में देखती है, हालांकि किसी को पहचान की आवश्यकता है। सरकार के रूप में एक बहुमूल्य छोटे बच्चे और भंडार के रूप में एक आदेश के बारे में सोचें (इनट्स अधिक उपयोगकर्ता के अनुकूल हैं!) :) – tuespetre

उत्तर

5

मैं दूसरे दृष्टिकोण से बाहर निकलना शुरू करना चाहता हूं। न केवल यह प्रतिद्वंद्वी लगता है, यह Command-Query Separation और Principle of Least Surprise जैसे कई अच्छे डिज़ाइन सिद्धांतों का भी उल्लंघन करता है।

शेष विकल्प डोमेन तर्क पर निर्भर करते हैं। डोमेन तर्क तय है कि एक आईडी के बिना एक आदेश अर्थहीन है तो आईडी आदेश के एक आवश्यक अपरिवर्तनीय है, और हम तो यह मॉडल चाहिए:

public class Order 
{ 
    private readonly int id; 

    public Order(int id) 
    { 
     // consider a Guard Clause here if you have constraints on the ID 
     this.id = id; 
    } 
} 

सूचना है कि readonly रूप id क्षेत्र चिह्नित करके हम इसे बना दिया है एक आविष्कार किसी दिए गए ऑर्डर इंस्टेंस के लिए हम इसे बदल नहीं सकते हैं। यह Domain-Driven Design के इकाई पैटर्न के साथ पूरी तरह से फिट बैठता है।

आईडी को नकारात्मक या शून्य होने से रोकने के लिए आप रक्षक में गार्ड क्लॉज डाल कर डोमेन लॉजिक को आगे बढ़ा सकते हैं।

अब तक आप शायद सोच रहे हैं कि यह डेटाबेस से स्वत: जेनरेट की गई आईडी के साथ कैसे काम करेगा। अच्छा, यह नहीं है।

यह सुनिश्चित करने का कोई अच्छा तरीका नहीं है कि आपूर्ति आईडी पहले से उपयोग में नहीं है।

कि आपके पास दो विकल्प के साथ छोड़ देता है:

  • बदलें एक Guid के लिए आईडी। यह किसी भी कॉलर को नए ऑर्डर के लिए एक अद्वितीय आईडी प्रदान करने की अनुमति देता है। हालांकि, इसके लिए आपको गुड्स को डेटाबेस कुंजी के रूप में भी उपयोग करने की आवश्यकता है।
  • एपीआई बदलें ताकि नया ऑर्डर बनाना ऑर्डर ऑब्जेक्ट न ले, बल्कि आपके द्वारा सुझाए गए ऑर्डर रेवेस्ट - ऑर्डर रेक्वेट ऑर्डर क्लास के लगभग समान हो सकता है, आईडी को घटा सकता है।

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

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

यदि यह दृष्टिकोण लिया जाता है, तो AddOrder विधि को ऑर्डर इंस्टेंस (या कम से कम आईडी) वापस करना होगा, अन्यथा हम अभी बनाए गए आदेश की आईडी नहीं जान सकते हैं। इससे हमें सीक्यूएस उल्लंघन का सामना करना पड़ता है, यही कारण है कि मैं पर निर्भर करता हूं कि एंटिटी आईडी के लिए मार्गदर्शिकाएं पसंद करते हैं।

+0

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

+0

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

+0

यदि ऑर्डर और ऑर्डर रिवेस्ट अलग हो जाते हैं तो यह रखरखाव नरक होगा, है ना?मेरा मतलब है, क्योंकि वे आईडी क्षेत्र को छोड़कर, एक दूसरे को पूरी तरह से प्रतिबिंबित करते हैं, उन्हें हर समय सह-विकास करना होगा। या क्या मैं कुछ न कुछ भूल रहा हूं? – vorou

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