2009-03-04 13 views
20

मैं कमजोर डोमेन मॉडल और चिंताओं की जुदाई के बारे में सवाल के कुछ पढ़ा है। एनीमिक डोमेन ऑब्जेक्ट्स पर डोमेन लॉजिक करने/जोड़ने के लिए सबसे अच्छी तकनीक क्या हैं? मेरे काम पर, हमारे पास एक सुंदर एनीमिक मॉडल है, और हम वर्तमान में डोमेन ऑब्जेक्ट्स पर डेटाबेस/व्यवसाय तर्क करने के लिए "सहायक" कक्षाओं का उपयोग कर रहे हैं। उदाहरण के लिए:तकनीक

public class Customer 
{ 
    public string Name {get;set;} 
    public string Address {get;set;} 
} 

public class Product 
{ 
    public string Name {get;set;} 
    public decimal Price {get;set;} 
} 

public class StoreHelper 
{ 
    public void PurchaseProduct(Customer c, Product p) 
    { 
     // Lookup Customer and Product in db 
     // Create records for purchase 
     // etc. 
    } 
} 

एप्लिकेशन एक खरीद करने की जरूरत है, यह StoreHelper बनाते हैं, और डोमेन वस्तुओं पर विधि कॉल करेगा। मेरे लिए, यह ग्राहक/उत्पाद कैसे भंडार करने के लिए खुद को बचाने के लिए पता करने के लिए के लिए कोई मतलब होगा, लेकिन आप शायद सहेजें() डोमेन वस्तुओं पर तरीकों नहीं करना चाहेंगे। यह ग्राहक की तरह एक विधि के लिए भी समझ में आएगा। खरीद (उत्पाद), लेकिन यह इकाई पर डोमेन तर्क डाल रहा है।

यहाँ कुछ तकनीकों मैं का सामना करना पड़ा, यकीन है कि जो अच्छा/बुरा कर रहे हैं नहीं कर रहे हैं:

  1. ग्राहक और उत्पाद एक "संस्था" का वर्ग है, जो एक सामान्य फैशन में बुनियादी CRUD संचालन (प्रदान करता है से विरासत शायद एक ओआरएम का उपयोग कर)।
    • पेशेवरों: प्रत्येक डेटा ऑब्जेक्ट स्वचालित रूप से CRUD संचालन मिलेगा, लेकिन फिर डेटाबेस/ORM से बंधा है
    • विपक्ष: यह वस्तुओं पर व्यापार कार्य की समस्या का समाधान नहीं होता है, और यह भी सभी डोमेन वस्तुओं बांध एक आधार इकाई है कि उपयुक्त नहीं होता है
  2. उपयोग सहायक CRUD संचालन और व्यापार तर्क
    • को संभालने के लिए यह मतलब है "शुद्ध डेटाबेस" के संचालन के लिए DAOs के लिए कक्षाएं, और अलग व्यवसाय सहायकों उनके लिए अयस्क व्यापार-विशिष्ट संचालन?
    • यह इस के लिए बेहतर गैर स्थिर या स्थिर सहायक वर्गों का उपयोग करने के है?
    • सकारात्मक: नहीं बहुत OO, बहुत आवेदन कोड में सहायकों उपयोग करने के लिए प्राकृतिक नहीं (सी कोड की तरह दिखता है)
  3. : डोमेन वस्तुओं किसी भी डेटाबेस/व्यापार तर्क (पूरी तरह से कमजोर)
  4. विपक्ष से जुड़ा नहीं है एक मनमाना भंडार
    • को बचाने के लिए डबल डिस्पैच तकनीक जहां इकाई के तरीकों है का उपयोग सकारात्मक: संस्थाओं के लिए कुछ अतिरिक्त तर्क संलग्न (हालांकि यह decoupled है)
    • : चिंताओं
    • विपक्ष के बेहतर जुदाई
  5. सी # 3.0, आप विस्तार तरीकों का उपयोग कर सकता है उसे स्पर्श करने से
    • यह एक वैध दृष्टिकोण है बिना एक डोमेन वस्तु को CRUD/व्यापार के तरीकों संलग्न करने के लिए है? पेशेवर/विपक्ष क्या हैं?
  6. अन्य तकनीकों?

इस से निपटने के लिए सबसे अच्छा तरीके क्या हैं? मैं बहुत DDD के लिए नया हूँ (मैं इवांस किताब पढ़ रहा हूँ - तो शायद कि मेरी आँखों खुलेगी)

उत्तर

7

मार्टिन Fowler डोमेन मॉडल के बारे में बहुत कुछ लिखा है, anemic domain models भी शामिल है। उन्होंने यह भी डोमेन मॉडल और डेटाबेस उपयोगी हो सकता है के लिए कई डिजाइन पैटर्न के संक्षिप्त विवरण (और यूएमएल वर्ग चित्र) है: Catalog of "Patterns of Enterprise Application Architecture"

मैं Active Record और Data Mapper पैटर्न को देख सुझाव है। आपकी समस्या का वर्णन है, उससे लगता अपने सहायक वर्गों की तरह डोमेन/व्यापार दोनों नियमों और डेटाबेस कार्यान्वयन विवरण होते हैं।

सक्रिय रिकॉर्ड अन्य डोमेन वस्तुओं (अपने Entity आधार वर्ग की तरह) में सहायक के डोमेन तर्क और डेटाबेस कोड कदम होगा। डेटा मैपर हेल्पर के डोमेन लॉजिक को डोमेन ऑब्जेक्ट्स और डेटाबेस कोड में एक अलग मैप ऑब्जेक्ट में ले जायेगा। प्रक्रियात्मक-शैली सहायक वर्गों की तुलना में या तो दृष्टिकोण अधिक ऑब्जेक्ट-उन्मुख होगा।

एरिक इवांस के "डोमेन प्रेरित डिजाइन" पुस्तक उत्कृष्ट है। यह थोड़ा सूखा हो जाता है, लेकिन यह निश्चित रूप से इसके लायक है। इन्फोक्यू में "Domain Driven Design Quickly" mini-book है जो इवांस की पुस्तक के लिए एक अच्छा परिचय है। इसके अलावा "डोमेन संचालित डिजाइन जल्दी" एक मुफ्त पीडीएफ के रूप में उपलब्ध है।

2

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

Interface IPurchase 
     Purchase(Product); 

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

14

आदेश, कमजोर मॉडल से बचने के लिए अपने सहायक वर्गों refactor में:

तर्क की तरह:
"Customer.PurchaseProduct (उत्पाद उत्पाद, भुगतान भुगतान)",
"Customer.KillCustomer (व्यक्ति हत्यारा, हथियार हथियार) "
सही" ग्राहक "डोमेन ऑब्जेक्ट में मौजूद होना चाहिए।

तर्क की तरह:
"Customer.IsCustomerAlive()"
"Customer.IsCustomerHappy()"
विनिर्देशों के लिए जाना चाहिए।

तर्क की तरह:
"Customer.Create()",
"Customer.Update()"
स्पष्ट रूप से खजाने के पास जाना चाहिए।

तर्क की तरह:
"Customer.SerializeInXml()"
"Customer.GetSerializedCustomerSizeInBytes()"
सेवाओं के लिए जाना चाहिए।

जटिल रचनाकारों को कारखानों में जाना चाहिए।

इस तरह मैं इसे देखता हूं। अगर कोई डीडीडी दृष्टिकोण की मेरी समझ पर टिप्पणी कर सकता है तो मुझे खुशी होगी।


संपादित करें:

कभी कभी - कमजोर डोमेन मॉडल shouldn't be avoided

मेरे उत्तर को संपादित करने के लिए संपादित किया गया कि डीडीडी पैटर्न लेने और पैटर्न छोड़ने के बारे में नहीं है।
डीडीडी हमारे बारे में सोचने के तरीके के बारे में है।

+0

ग्राहक को संभालने के लिए अलग-अलग कक्षाओं की तरह लगता है। किसी भी जटिल को संभालने के लिए सेवा के साथ, इसे अधिकांश कक्षाओं में क्यों नहीं फेंक दें? –

+0

मेरा जवाब नरक की तरह पुराना है। : डी –

+0

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

0

एक दृष्टिकोण जिसका आपने उल्लेख नहीं किया है वह आपके डेटा एक्सेस को संभालने के लिए एओपी का उपयोग कर रहा है। इस दृष्टिकोण के मेरे हालिया उपयोग का एक उदाहरण (हालांकि पोस्टिंग उद्देश्यों के लिए काफी सरल) यह था कि मेरे पास Account डोमेन इकाई थी जिसमें debit विधि थी, जो खाता से सफल डेबिट करने के लिए आवश्यक व्यावसायिक तर्क को समाहित करता था।

एनबी। सभी कोड AspectJ AOP अंकन के साथ जावा है ...

public boolean debit(int amount) { 
    if (balance - amount >= 0) { 
     balance = balance - amount; 
     return true; 
    } 
    return false; 
} 
मेरे पहलू में इंजेक्शन उचित भंडार के साथ

, मैं तो इस विधि के लिए कॉल अवरोधन करने ...

pointcut debit(Account account,int amount) : 
    execution(boolean Account.debit(int)) && 
    args(amount) && 
    target(account); 

एक pointcut इस्तेमाल किया।

after(Account account, int amount) returning (boolean result) : debit(account,amount) { 
    if (result) getAccountRepository().debit(account, amount); 
} 

मेरी राय में इस चिंताओं का एक अच्छा जुदाई देता है, और अपने डोमेन संस्थाओं y के व्यापार तर्क पर पूरी तरह से ध्यान केंद्रित करने की अनुमति देता है: ..और कुछ सलाह लागू किया हमारा आवेदन