7

मैं डोमेन मॉडल, पीओसीओ और डीडीडी के लिए नया हूं, इसलिए मैं अभी भी कुछ विचारों के आसपास अपना सिर लेने की कोशिश कर रहा हूं।डोमेन मॉडल और पीओसीओ कक्षाओं के साथ काम करते समय, प्रश्न कहां जाते हैं?

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

उदाहरण के लिए, मान लीजिए कि मेरे पास एक इकाई ऑर्डर है जिसमें OrdemItems का संग्रह है। मैं सबसे सस्ता ऑर्डर आइटम प्राप्त करना चाहता हूं, किसी भी कारण से, या शायद ऑर्डर आइटमों की एक सूची जो स्टॉक में नहीं हैं। मैं जो नहीं करना चाहता हूं वह सभी ऑर्डर आइटम्स को स्टोरेज से पुनर्प्राप्त करना और बाद में फ़िल्टर करना (बहुत महंगा) है, इसलिए मैं किसी भी तरह से "SELECT .. ITEM.INSTOCK = FALSE" प्रकार के डीबी क्वेरी को समाप्त करना चाहता हूं। मैं अपनी इकाई में एसक्यूएल क्वेरी नहीं चाहता हूं, या अगर कोई मुझे विशिष्ट प्लेटफॉर्म में जोड़ देगा, जैसे LINQ2SQL पर NHibernate क्वेरी। उस मामले में आम समाधान क्या है?

उत्तर

2

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

+0

क्या आपके पास ऑर्डर क्लास में इंजेक्शन दिया गया था (ऑर्डर कन्स्ट्रक्टर के हिस्से के रूप में IOrderRepository वाली कुछ पंक्ति), या क्या आपके पास यह बाहर होगा? यदि हां, तो ऑर्डर क्लास में आपके पास क्या होगा? मुझे यकीन नहीं है कि स्टॉक आइटम से बाहर क्या है, ज्ञान/बिज़ नियम –

+0

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

+0

@Morendil I आधा सहमत है: किसी ऑर्डर को इसके भंडार के बारे में कुछ भी नहीं पता होना चाहिए, लेकिन उस * से * डोमेन ऑब्जेक्ट को * किसी भी * भंडार के बारे में पता होना चाहिए। यदि DomainObjectA को DomainObjectB का एक उदाहरण चाहिए, तो कुछ उच्च स्तरीय समन्वयक को अपने भंडारों से बात करनी चाहिए और चीज़ों को हुक करना चाहिए। –

3

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

आदर्श रूप से, भंडार के अंदर क्वेरी निर्माण करना एक अच्छा विचार होगा, हालांकि मैं वहां एक ओआरएम का उपयोग करूंगा।

यहाँ Repository Pattern.

+0

तो मेरे ऑर्डर क्लास के अंदर से मैं _orderRepository.GetOrderItemsNotInStock (यह) जैसा कुछ करूँगा? –

+0

नहीं, आपके पास कक्षा ऑर्डर रिपोजिटरी होगी, जिसमें GetById (OrderId) जैसे फ़ंक्शन होंगे। ऑर्डर क्लास के बाहर रिपोजिटरी मौजूद है, ऑर्डर क्लास आदर्श रूप से बहुत छोटी होगी, शायद गेटर्स और सेटर्स के साथ गुण, साथ ही प्रासंगिक तर्क –

+0

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

3

संस्थाओं के मार्टिन फाउलर की परिभाषा है एक डोमेन के "इकाइयों" कर रहे हैं। रिपोजिटरीज और सेवाएं संदर्भ उन्हें, इसके विपरीत नहीं। इस बारे में इस बारे में सोचें: क्या आप अपनी जेब में डीएमवी लेते हैं?

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

प्रश्नों के लिए घर खोजने की कठिनाई मुझे सेवाओं के बारे में सोचने के लिए प्रेरित करती है। इस मामले में, वे के बारे में कुछOrder का प्रतिनिधित्व करेंगे जो Order के लिए स्वयं को जानना मुश्किल है।

डोमेन परियोजना में इरादे की घोषणा:

public interface ICheapestItemService 
{ 
    OrderItem GetCheapestItem(Order order); 
} 

public interface IInventoryService 
{ 
    IEnumerable<OrderItem> GetOutOfStockItems(Order order); 
} 

डेटा परियोजना में कार्यान्वयन घोषित:

public class CheapestItemService : ICheapestItemService 
{ 
    private IQueryable<OrderItem> _orderItems; 

    public CheapestItemService(IQueryable<OrderItem> orderItems) 
    { 
     _orderItems = orderItems; 
    } 

    public OrderItem GetCheapestItem(Order order) 
    { 
     var itemsByPrice = 
      from item in _orderItems 
      where item.Order == order 
      orderby item.Price 
      select item; 

     return itemsByPrice.FirstOrDefault(); 
    } 
} 

public class InventoryService : IInventoryService 
{ 
    private IQueryable<OrderItem> _orderItems; 

    public InventoryService(IQueryable<OrderItem> orderItems) 
    { 
     _orderItems = orderItems; 
    } 

    public IEnumerable<OrderItem> GetOutOfStockItems(Order order) 
    { 
     return _orderItems.Where(item => item.Order == order && !item.InStock); 
    } 
} 

यह उदाहरण किसी भी LINQ प्रदाता के साथ काम करता है। वैकल्पिक रूप से, गंदे काम करने के लिए डेटा प्रोजेक्ट NHHernate के ISession और ICriteria का उपयोग कर सकता है।

+0

मुझे यकीन है कि मुझे कुछ याद आ रहा है, लेकिन जब भी मैं इस तरह कुछ लागू करने का प्रयास करता हूं, तो यह "किसी भी" LINQ प्रदाता के साथ काम नहीं करता है। उदाहरण के लिए GetCheapestOrderItem में क्वेरी अलग-अलग दिखाई दे सकती है यदि मैं एसडीएस, ईएफ, या एल 2 एस का उपयोग कर रहा था, खासकर यदि मुझे जॉइन या अन्य गैर-मामूली क्वेरी तर्क करना है। – Daniel

+0

यह लीकी अबास्ट्रक्शन के बारे में एक सामान्य चिंता है। ये प्रश्न मॉडल के अर्थशास्त्र पर केंद्रित हैं। यह उन अर्थशास्त्रों को मैकेनिक्स ("अलग दिखने वाला" भाग) में अनुवाद करने के लिए IQueryable कार्यान्वयन पर निर्भर है। –

-2

सेवा परत में।

0

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

मुझे लगता है कि सवाल यह हो जाता है कि आप वाकई ऑर्डर को Aggregate Root के रूप में देखना चाहते हैं, या फिर आप अपने डेटा एक्सेस लेयर से ऑर्डरइटम की मनमानी सूचियों को खींचने में सक्षम होना चाहते हैं।

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

अगर वह सही मायने में है नहीं मामले और आप डेटाबेस में फिल्टर करने के लिए की जरूरत है, तो आप एक अलग OrderItem भंडार ऐसे ही प्रश्नों प्रदान करेगा होने पर विचार कर सकते "मुझे OrderItems के सभी देना इस आदेश है कि नहीं कर रहे हैं के लिए स्टॉक में"। फिर आप उन्हें IList<OrderItem> (या IEnumerable<OrderItem>) के रूप में वापस कर देंगे, क्योंकि वे एक पूर्ण ऑर्डर नहीं हैं, बल्कि ऑर्डरइटम के कुछ फ़िल्टर किए गए संग्रह हैं।

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