2012-08-14 12 views
9

मैं डोमेन संचालित डिजाइन priciples का उपयोग कर अपने एएसपी.नेट एमवीसी ऐप को फिर से लिखने पर काम कर रहा हूं। मैं अपनी उपयोगकर्ता इकाई को प्रमाणित करने की कोशिश कर रहा हूं। अब तक मैं बुनियादी नियमों को सत्यापित करने में सक्षम हूं (जैसे उपयोगकर्ता नाम और पासवर्ड एक गैर शून्य/सफेद स्थान स्ट्रिंग है)। हालांकि नियमों में से एक, मुझे यह सुनिश्चित करना होगा कि उपयोगकर्ता नाम अद्वितीय है। हालांकि मुझे ऐसा करने के लिए डेटाबेस इनरॉर्डर तक पहुंच की आवश्यकता है, जिसका अर्थ है कि मुझे अपनी उपयोगकर्ता इकाई में अपनी IUserRepository इंजेक्ट करना होगा।डीडीडी डोमेन मॉडल कॉम्प्लेक्स प्रमाणीकरण

public class User 
{ 
    private readonly IUserRepository _userRepository; 
    public User(IUserRepository repo) 
    { 
     _userRepository = repo; 
    } 

    public override void Validate() 
    { 
     //Basic validation code 
     if (string.IsNullOrEmpty(Username)) 
      throw new ValidationException("Username can not be a null or whitespace characters"); 
     if (string.IsNullOrEmpty(Password)) 
      throw new ValidationException("Password can not be a null or whitespace characters"); 

     //Complex validation code 
     var user = _userRepository.GetUserByUsername(Username); 
     if (user != null && user.id != id) 
      throw new ValidationException("Username must be unique") 
    } 
} 

हालांकि ऐसा लगता है ... ठीक है। मेरी इकाई को मेरी भंडार पर निर्भर करना एक बुरा विचार जैसा लगता है (अगर मैं गलत हूं तो मुझे सही करें)। लेकिन इकाई में सत्यापन कोड होने से समझ में आता है। जटिल सत्यापन कोड डालने का सबसे अच्छा स्थान कहां है?

+2

यह भी देखें [यह उत्तर] (http://stackoverflow.com/a/9676307/706456) – oleksii

उत्तर

8

हालांकि ऐसा लगता है ... ठीक है। मेरी इकाई को मेरी भंडार पर निर्भर करना एक बुरा विचार जैसा लगता है (अगर मैं गलत हूं तो मुझे सही करें)।

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

लेकिन इकाई में सत्यापन कोड समझ में आता है। जटिल सत्यापन कोड डालने का सबसे अच्छा स्थान कहां है?

मुझे लगता है कि आप 'सत्यापन' को अधिक सामान्य कर सकते हैं। मैं 'मान्य' विधि से छुटकारा पाउंगा और यह सुनिश्चित कर दूंगा कि ऑब्जेक्ट पहले स्थान पर 'अमान्य' स्थिति में नहीं आता है। मैं कुछ महीने पहले answered इसी तरह के सवाल।

अब विशिष्टता नियम पर वापस जाएं। मुझे लगता है कि यह उन उदाहरणों में से एक है जहां डीडीडी 'लीक' थोड़ा सा है, इस अर्थ में कि इस व्यापार नियम को लागू करने से डोमेन कोड में पूरी तरह व्यक्त नहीं किया जा सकता है। मैं इसे इस तरह के दृष्टिकोण होगा:

// repository 
interface Users { 
    // implementation executes SQL COUNT in case of relation DB 
    bool IsNameUnique(String name); 

    // implementation will call IsNameUnique and throw if it fails 
    void Add(User user); 
} 

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

4

हालांकि इस लगता है ... अच्छी तरह से गलत

नहीं, यह बिल्कुल गलत नहीं है। डोमेन मॉडल को एक भंडार पर निर्भर होने के बाद पूरी तरह से ठीक है। इसके अलावा आपने एक इंटरफ़ेस के पीछे अपनी रिपॉजिटरी को सारणीबद्ध किया है जो कि बेहतर है।

या कन्स्ट्रक्टर इंजेक्शन का उपयोग न करें। मान्य विधि के लिए भंडार दर्रा अगर यह केवल एक यह की जरूरत है:

public class User 
{ 
    public void Validate(IUserRepository repo) 
    { 
     //Basic validation code 
     if (string.IsNullOrEmpty(Username)) 
      throw new ValidationException("Username can not be a null or whitespace characters"); 
     if (string.IsNullOrEmpty(Password)) 
      throw new ValidationException("Password can not be a null or whitespace characters"); 

     //Complex validation code 
     var user = repo.GetUserByUsername(Username); 
     if (user != null && user.id != id) 
      throw new ValidationException("Username must be unique") 
    } 
} 
+0

आपके उत्तर के लिए धन्यवाद। समस्या यह है कि अब मुझे उपयोगकर्ता बनाने के लिए IUserRepository का कार्यान्वयन करना होगा, जिसका अर्थ है कि मुझे इकाइयों के लिए निर्भरताओं को इंजेक्ट करने के लिए आईओसी का उपयोग करना होगा। यह मूल्य के मुकाबले अधिक कोड लगता है, विशेष रूप से जब मैं ऑब्जेक्ट का निर्माण करते समय विशेषताओं को प्रारंभ करने का लाभ लेता हूं उदाहरण var user = new user {उपयोगकर्ता नाम = "व्यवस्थापक"}; –

+0

इस मामले में कन्स्ट्रक्टर इंजेक्शन का उपयोग न करें। वैध विधि को भंडार पास करें यदि यह केवल इसकी आवश्यकता है। –

1

मैं @oleksii से सहमत हैं, using the specification pattern एक बेहतर तरीका है। प्रमाणीकरण के अलग-अलग संदर्भों में अलग-अलग अर्थ हैं, इसलिए इस चिंता को विभाजित करने के लिए मुझे समझ में आता है।

8

इस प्रकार की स्थितियों में उपयोग किए जाने वाले पैटर्न को एप्लिकेशन सेवा में इस प्रकार के सत्यापन तर्क को रखना है।कुछ हद तक, यह समझ में आता है क्योंकि User इकाई केवल अपनी वैधता के लिए ज़िम्मेदार है, न कि उपयोगकर्ताओं के सेट की वैधता। आवेदन सेवा विधि है कि उपयोगकर्ता बनाता है यह looklike कर सकते हैं:

public User CreateUser(string userName) 
{ 
    if (this.userRepository.Exists(userName)) 
    throw new Exception(); 
    var user = new User(userName); 
    this.userRepository.Add(user); 
    return user; 
} 

आवेदन सेवा एक अमूर्त वहाँ आप DDD रोजगार या नहीं कर रहे हैं, चाहे है और इसलिए जब DDD देता में वापस आने का एक अच्छी जगह है वह यह है कि टकराव।

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