2010-04-09 18 views
15

मैंने ओओपी डीडीडी/पीओईएए/गैंग ऑफ चार पर कुछ किताबें पढ़ी हैं और उनमें से कोई भी सत्यापन के विषय को कवर नहीं कर रहा है - ऐसा लगता है कि डेटा हमेशा वैध है।ओओपी डिजाइन - आप कहां/कब गुणों को मान्य करते हैं?

मैं इस पोस्ट (OOP Design Question - Validating properties) के उत्तरों से एकत्र करता हूं कि एक ग्राहक को केवल मान्य डोमेन डोमेन ऑब्जेक्ट पर संपत्ति मान सेट करने का प्रयास करना चाहिए।

इस व्यक्ति को एक ऐसी ही सवाल है कि अनुत्तरित बना हुआ है कहा है: http://bytes.com/topic/php/answers/789086-php-oop-setters-getters-data-validation#post3136182

तो आप इसे कैसे मान्य है सुनिश्चित करते हैं? क्या आपके पास प्रत्येक गेटर और सेटर के साथ 'सत्यापनकर्ता विधि' है?

  • isValidName()
  • setName()
  • getName()

मैं OOP डेटा सत्यापन के बारे में कुछ महत्वपूर्ण बुनियादी ज्ञान लापता हो रहे हैं - तुम मुझे एक किताब है कि कवर को इंगित कर सकते हैं इस विषय में विस्तार से? - अर्थात। अलग-अलग प्रकार के सत्यापन/इनवेरिएंट/हैंडलिंग फीडबैक/अपवादों का उपयोग करने के लिए या नहीं आदि

+1

बस ऐसे ही जोड़ने के लिए, कुछ और अनुसंधान के बाद, मैंने पाया यह उपयोगी: http://devcity.net/Articles/381/1/article.aspx –

उत्तर

7

मेरे अनुभव में, सत्यापन होता है जहां मानव/उपयोगकर्ता इनपुट होता है। और यह आमतौर पर होता है जहां आप कुछ बदलने के लिए अपनी विधि के माध्यम से अनुमति देते हैं। अपने उदाहरण में, मैं विधि के लिए सत्यापन के लिए जाना होगा:

setName() 

तो ऐसा होता है जहां मूल्यों के इनपुट की अनुमति देते हैं/मान सेट जो पता चला है सेटर तरीकों किया जाना है।

1

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

1

संक्षेप में, हमेशा मान्य करें। लंबे समय तक, अपने सत्यापन को सभी एक साथ, साथ ही 'रास्ते में' न करें। यह आपके कोड को सुव्यवस्थित रहने में मदद करेगा और डीबगिंग भ्रम में मदद करेगा।

1

यदि आप अपनी कक्षा का उपयोग करने वाले कोड को नियंत्रित करते हैं, तो आपको ऑब्जेक्ट के चर (सार्वजनिक गुणों के माध्यम से) में हेरफेर करने का प्रयास करने से पहले मान्य होना चाहिए। यदि आप ऐसे परिदृश्य की उम्मीद कर रहे हैं जहां आप नहीं जानते कि आपकी कक्षा का उपयोग कैसे किया जाए, तो हाँ, आपको संपत्ति के भीतर मान्य होना चाहिए, जो कि वे कम या कम हैं। जाहिर है, यह "वैध नाम है" की परिभाषा मानता है एक वस्तु का निहित एक स्थिर व्यापार नियम है।

दोनों स्तरों पर मान्य होना निश्चित रूप से जाने का सबसे सुरक्षित मार्ग है।

+0

हाँ 'अगर है' की परिभाषा काफी है एक भ्रमित क्षेत्र भी। इस सवाल को विश्वसनीय होने के लिए कुछ संदर्भ की आवश्यकता है - मुझे अपने आप को लिखने की चीज़ें मिल रही हैं जैसे: ऑर्डर-> IsValidOrderAccordingToPaymentStrategy() इस विषय पर क्लासिक पुस्तक के बारे में सुनने की उम्मीद कर रहा था कि हर कोई मुझे पढ़ता है। –

+0

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

+0

लेकिन आप अपने गाय को जहरीले मशरूम से भरे चरागाह में नहीं रखना चाहते हैं, भले ही आपका गाय उन्हें नहीं खाएगा। :) – sweaver2112

1

ओओपी का एक महत्वपूर्ण हिस्सा हमेशा आपकी वस्तु को वैध स्थिति में रखता है। इसलिए, ऑब्जेक्ट को संशोधित करने वाले इनपुट के बाद सत्यापन किया जाना चाहिए।

गुण/सेट, पैरामीटर और कन्स्ट्रक्टर के पैरामीटर से आने वाले डेटा को सत्यापित करना हमेशा अच्छा होता है।

+0

"ओओपी का एक महत्वपूर्ण हिस्सा हमेशा अपनी वस्तु को वैध स्थिति में रखना है" - मुझे यह पसंद है, धन्यवाद। – Jimbo

3

किसी डोमेन ऑब्जेक्ट के इनवेरिएंट (जो हमेशा संतुष्ट होना चाहिए) के अर्थ में वैध के बीच अंतर करना महत्वपूर्ण है और कुछ लोग क्या कहते हैं "contextual validation." उदाहरण के लिए, एक नकारात्मक बैंक खाता वाला कोई ग्राहक" अमान्य है? "नहीं, लेकिन वे कुछ प्रकार के लेनदेन करने के लिए अधिकृत नहीं हो सकते हैं।यह प्रासंगिक सत्यापन है, "प्रत्येक ग्राहक इकाई के पास एक गैर-शून्य आईडी होना चाहिए," जो एक अलग प्रकार की सत्यापन पूरी तरह से है।

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

उदाहरण के लिए, यदि आपके पास Student डोमेन ऑब्जेक्ट है, तो इसे सीधे उपयोगकर्ता इंटरफ़ेस में हेरफेर न करें। Student उदाहरण बनाने के बजाय, आपके विचार StudentBuilder उदाहरण बनाते हैं जो मॉडल को वैध Student डोमेन ऑब्जेक्ट बनाने के लिए आवश्यक हैं।

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

+0

हां यह समझ में आता है। आने वाले डेटा को रखने के लिए मुझे 'विनिर्देश वस्तु' या 'डेटा पिंजरे' बनाकर ऐसा करने का तरीका है - लेकिन इससे पहले इसके बारे में अनिश्चित था। –

1

यह प्रोग्रामिंग की आपकी शैली पर निर्भर करता है, क्योंकि विकिपीडिया में अधिक विस्तृत स्पष्टीकरण हैं, मैं सतह को खरोंच कर दूंगा और विकिपीडिया से लिंक करूंगा। (हाँ, मैं आलसी हूं। :-))

नोट: यह सब उपयोगकर्ता इनपुट पर लागू नहीं होता है। आपको इसे किसी भी तरह से मान्य करना होगा। मैं बस व्यापार तर्क वर्गों के बारे में बात कर रहा हूं जिसे किसी भी तरह से उपयोगकर्ता इनपुट के साथ जोड़ा जाना चाहिए। :-)

  • रक्षात्मक

दूसरों के द्वारा उल्लेख किया है, आप अपनी सीमा के लिए हर संपत्ति को लागू करेगा। मैं अक्सर उन असफलताओं को इंगित करने के लिए रनटाइम अपवाद (जावा) फेंक दिया।

Wikipedia on Defensive Programming

  • अनुबंध

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

Wikipedia on Design by Contract

+0

मुझे डिज़ाइन बाय कॉन्ट्रैक्ट (टीएम) जानकारी बहुत उपयोगी मिली - विशेष रूप से 'असफल असफल' का विचार जो इन सभी उत्तरों का एक चल रहा विषय प्रतीत होता है। आपूर्तिकर्ता के काम को यथासंभव आसान बनाएं और ग्राहक को यह तय करें कि मूल्य अस्वीकार होने पर क्या करना है। –

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