7

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

मैंने अपने डोमेन मॉडल को सुपर-डुप्कर पीओसीओ के रूप में फिर से काम किया है और यह सुनिश्चित करने के लिए कि संपत्ति मूल्यों को डोमेन को समझ में आता है, इस बारे में कुछ चिंताओं के साथ छोड़ दिया गया है।

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

मेरे पास कुछ समाधान हैं (उत्तर में पोस्ट करेंगे), लेकिन उनके पास नुकसान हैं और मुझे आश्चर्य है कि इस दुविधा को हल करने के लिए कुछ पसंदीदा दृष्टिकोण क्या हैं?

उत्तर

6

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

+1

में निर्दयी होना चाहिए, ये वस्तुएं व्यवहार को समाहित नहीं करती हैं। यह पूरी बात है। वे मेरे डोमेन का प्रतिनिधित्व करते हैं। बस इतना ही। व्यवहार कहीं और प्रदान किया जाता है। –

+0

आपके डोमेन का कोई व्यवहार नहीं है? –

+1

डोमेन मॉडल का कोई व्यवहार नहीं है। व्यवहार अलग से जुड़ा हुआ है। सेवाएं मॉडल का उपयोग करके सामान करती हैं। कम से कम यह पूरी डीडीडी चीज पर मेरा पढ़ा है। –

0

मुझे लगता है कि तर्क के लिए शायद सबसे अच्छा स्थान होगा, वास्तव में, लेकिन यह सिर्फ मुझे है। आपके पास कुछ प्रकार की IsValid विधि हो सकती है जो सभी शर्तों को भी जांचती है और सच/गलत लौटाती है, हो सकता है कि किसी प्रकार का त्रुटि संदेश संग्रह हो लेकिन यह एक iffy विषय है क्योंकि त्रुटि संदेश वास्तव में डोमेन मॉडल का हिस्सा नहीं हैं। मैं थोड़ी पक्षपातपूर्ण हूं क्योंकि मैंने आरओआर के साथ कुछ काम किया है और यह अनिवार्य रूप से इसके मॉडल क्या करता है।

+0

एसआरपी - क्या आपका मॉडल असली दुनिया वस्तु का प्रतिनिधित्व करने या इनपुट मान्य करने के लिए ज़िम्मेदार है? इस –

3

मैं हमेशा लोगों को "मान्य" या "IsValid" विधि के लिए तर्क सुनता हूं।

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

तो मैं "IsValidForNewContract", "IsValidForTermination" या इसी तरह से पसंद करता हूं, क्योंकि मेरा मानना ​​है कि अधिकांश परियोजनाएं प्रति वर्ग ऐसे कई वैध/राज्यों के साथ समाप्त होती हैं। इसका मतलब यह भी है कि मुझे कोई इंटरफ़ेस नहीं मिला है, लेकिन मैं समेकित मान्यताओं को लिख सकता हूं कि पढ़ना व्यवसाय की स्थितियों को बहुत अच्छी तरह से प्रतिबिंबित करता है।

मैं सच में विश्वास है कि इस मामले में सामान्य समाधान बहुत बार दूर क्या महत्वपूर्ण है से ध्यान केंद्रित लेते हैं - क्या कोड कर रही है - तकनीकी लालित्य में एक बहुत ही मामूली लाभ (इंटरफेस, प्रतिनिधि या जो कुछ भी) के लिए। बस इसके लिए मुझे वोट दें;)

2

एक समाधान यह है कि प्रत्येक ऑब्जेक्ट का DataAccessObject मान्यकर्ताओं की एक सूची लेना है। जब सहेजें कहा जाता है यह प्रत्येक सत्यापनकर्ता के खिलाफ एक चेक preforms:

public class ServiceEndDateValidator : IValidator<Service> { 
    public void Check(Service s) { 
    if(s.EndDate > s.Contract.EndDate) 
     throw new InvalidOperationException(); 
    } 
} 

public class ServiceDao : IDao<Service> { 
    IValidator<Service> _validators; 
    public ServiceDao(IEnumerable<IValidator<Service>> validators) {_validators = validators;} 
    public void Save(Service s) { 
    foreach(var v in _validators) 
     v.Check(service); 
    // Go on to save 
    } 
} 

लाभ, बहुत स्पष्ट SoC है, नुकसान() है कि हम सहेजें जब तक जांच नहीं मिलता है कहा जाता है।

0

एक और संभावना है मेरी वर्गों में से प्रत्येक को लागू

public interface Validatable<T> { 
    public event Action<T> RequiresValidation; 
} 

और प्रत्येक वर्ग के लिए प्रत्येक सेटर सेट करने से पहले घटना बढ़ा है (शायद मैं विशेषताओं के माध्यम से इस लक्ष्य को हासिल कर सकते हैं) है।

लाभ वास्तविक समय सत्यापन जांच है। लेकिन मेसीयर कोड और यह अस्पष्ट है कि अटैचिंग करना चाहिए।

2

अतीत में मैंने आमतौर पर एक सेवा के सत्यापन के लिए सत्यापन किया है, जैसे सत्यापन प्रमाणीकरण। यह सिद्धांत रूप में अभी भी विज्ञापन डीडीडी के दर्शन के लिए सुनता है।

आंतरिक रूप से इसमें वैलिडेटर्स का संग्रह होगा और सार्वजनिक तरीकों का एक बहुत ही सरल सेट जैसे वैलिडेट() जो त्रुटि ऑब्जेक्ट का संग्रह वापस कर सकता है।

बहुत बस, सी # में कुछ इस तरह

public class ValidationService<T> 
{ 
    private IList<IValidator> _validators; 

    public IList<Error> Validate(T objectToValidate) 
    { 
    foreach(IValidator validator in _validators) 
    { 
     yield return validator.Validate(objectToValidate); 
    } 
    } 
} 

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

+0

वह समानांतर पदानुक्रम नहीं बनायेगा http://stackoverflow.com/questions/778449/code-smell-or-not-validators-and-models-share-same-kind-of-hiereachy – Surya

+0

सूर्य, क्या आप समझा सकते हैं कि आप क्या कर सकते हैं इसका मतलब है? मैं आगे बताने की कोशिश करूंगा ... – Xian

0

यहां एक और संभावना है। डोमेन ऑब्जेक्ट पर प्रॉक्सी या सजावटी के माध्यम से सत्यापन किया जाता है:

public class ServiceValidationProxy : Service { 
    public override DateTime EndDate { 
    get {return EndDate;} 
    set { 
     if(value > Contract.EndDate) 
     throw new InvalidOperationexception(); 
     base.EndDate = value; 
    } 
    } 
} 

लाभ: तत्काल सत्यापन। आसानी से एक आईओसी के माध्यम से कॉन्फ़िगर किया जा सकता है।

नुकसान: यदि कोई प्रॉक्सी, मान्य गुण वर्चुअल होना चाहिए, यदि सजावटकर्ता सभी डोमेन मॉडल इंटरफ़ेस-आधारित होना चाहिए। प्रमाणीकरण कक्षाएं थोड़ा हेवीवेट खत्म हो जाएंगी - प्रॉक्सी को कक्षा का उत्तराधिकारी होना होगा और सजावटी को सभी विधियों को लागू करना होगा। नामकरण और संगठन भ्रमित हो सकता है।

3

मेरा एक सहयोगी एक विचार के साथ आया जिसने बहुत अच्छी तरह से काम किया। हम इसके लिए कभी भी महान नाम के साथ नहीं आए, लेकिन हमने इसे इंस्पेक्टर/न्यायाधीश कहा।

इंस्पेक्टर एक ऑब्जेक्ट को देखेगा और आपको बताए गए सभी नियमों को बताएगा। न्यायाधीश फैसला करेगा कि इसके बारे में क्या करना है। यह अलगाव हमें कुछ चीजें करने देता है। यह हमें सभी नियमों को एक ही स्थान पर रखता है (इंस्पेक्टर) लेकिन हमारे पास कई न्यायाधीश हो सकते हैं और संदर्भ द्वारा न्यायाधीश का चयन कर सकते हैं।

एकाधिक न्यायाधीशों के उपयोग का एक उदाहरण नियम के चारों ओर घूमता है जिसमें कहा गया है कि ग्राहक के पास एक पता होना चाहिए। यह एक मानक तीन स्तरीय ऐप था। यूआई स्तर में न्यायाधीश कुछ ऐसा उत्पादन करेगा जो यूआई उन क्षेत्रों को इंगित करने के लिए उपयोग कर सकता है जिन्हें भरना था। यूआई न्यायाधीश ने अपवाद नहीं फेंक दिया। सेवा परत में एक और न्यायाधीश था। यदि इसे सहेजने के दौरान किसी पते के बिना ग्राहक को मिला तो यह अपवाद फेंक देगा। उस बिंदु पर आपको चीजों को आगे बढ़ने से रोकना होगा।

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

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

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