मुझे यह जानने में दिलचस्पी है कि आप किस तकनीक का उपयोग किसी ऑब्जेक्ट के दौरान किसी ऑब्जेक्ट की आंतरिक स्थिति को सत्यापित करने के लिए कर रहे हैं, जो कि अपने स्वयं के दृष्टिकोण से, केवल खराब आंतरिक स्थिति या आविष्कार उल्लंघन के कारण विफल हो सकता है।आप ऑब्जेक्ट की आंतरिक स्थिति को कैसे सत्यापित करते हैं?
मेरे प्राथमिक ध्यान, सी पर ++ है के बाद से सी # में सरकारी और प्रचलित तरीका एक अपवाद फेंकने के लिए है, और C++ सिर्फ एक एकल तरीका यह (ठीक है, वास्तव में नहीं सी # में या तो, मुझे पता है क्या करना नहीं है उस)।
ध्यान दें कि मैं फ़ंक्शन पैरामीटर सत्यापन के बारे में बात नहीं कर रहा हूं, लेकिन क्लास इनवेरिएंट अखंडता जांच की तरह अधिक है।
उदाहरण के लिए, मान लें कि हम Printer
ऑब्जेक्ट Queue
पर एक प्रिंट जॉब असीमित रूप से चाहते हैं। Printer
के उपयोगकर्ता के लिए, वह ऑपरेशन केवल सफल हो सकता है, क्योंकि एक असीमित कतार परिणाम किसी अन्य समय पहुंचने के साथ आता है। इसलिए, कॉलर को व्यक्त करने के लिए कोई प्रासंगिक त्रुटि कोड नहीं है।
लेकिन Printer
ऑब्जेक्ट पर, आंतरिक स्थिति खराब होने पर यह ऑपरेशन विफल हो सकता है, यानी, क्लास इनवेरिएंट टूटा हुआ है, जिसका मूल रूप से अर्थ है: एक बग। यह स्थिति Printer
ऑब्जेक्ट के उपयोगकर्ता के लिए किसी भी ब्याज की जरूरी नहीं है।
व्यक्तिगत रूप से, मैं आंतरिक राज्य सत्यापन की तीन शैलियों को मिश्रित करता हूं और मैं वास्तव में यह तय नहीं कर सकता कि कौन सा सबसे अच्छा है, यदि कोई है, तो केवल कौन सा सबसे खराब है। मैं इन पर आपके विचार सुनना चाहता हूं और यह भी कि आप इस मामले पर अपने किसी भी अनुभव और विचार साझा करते हैं।
पहली शैली मैं का उपयोग करें - बेहतर भ्रष्ट डेटा की तुलना में चलाया तरह से असफल: -:
void Printer::Queue(const PrintJob& job)
{
// Validate the state in debug builds only.
// Break into the debugger in debug builds.
// Always proceed with the queuing, also in a bad state.
DebugAssert(IsValidState());
// Continue with queuing, parameter checking, etc.
// Generally, behavior is now undefined, because of bad internal state.
// But, specifically, this often means an access violation when
// a NULL pointer is dereferenced, or something similar, and that crash will
// generate a dump file that can be used to find the error cause during
// testing before shipping the product.
}
तीसरे शैली बेहतर दुर्घटना भ्रष्ट डेटा की तुलना में बेकाबू
void Printer::Queue(const PrintJob& job)
{
// Validate the state in both release and debug builds.
// Never proceed with the queuing in a bad state.
if(!IsValidState())
{
throw InvalidOperationException();
}
// Continue with queuing, parameter checking, etc.
// Internal state is guaranteed to be good.
}
दूसरी शैली मैं का उपयोग मैं उपयोग करता हूं - भ्रष्ट डेटा से बेहतर चुपचाप और रक्षात्मक रूप से जमानत:
void Printer::Queue(const PrintJob& job)
{
// Validate the state in both release and debug builds.
// Break into the debugger in debug builds.
// Never proceed with the queuing in a bad state.
// This object will likely never again succeed in queuing anything.
if(!IsValidState())
{
DebugBreak();
return;
}
// Continue with defenestration.
// Internal state is guaranteed to be good.
}
मेरा कमेन शैलियों के लिए टीएस:
- मुझे लगता है कि मैं दूसरी शैली पसंद करता हूं, जहां विफलता छिपी नहीं है, बशर्ते कि एक प्रवेश उल्लंघन वास्तव में एक दुर्घटना का कारण बनता है।
- यदि यह आविष्कार में शामिल एक पूर्ण सूचक नहीं है, तो मैं पहली शैली की तरफ झुकता हूं।
- मैं वास्तव में तीसरी शैली को नापसंद करता हूं, क्योंकि यह बहुत सारी बग छुपाएगा, लेकिन मैं उन लोगों को जानता हूं जो इसे उत्पादन कोड में पसंद करते हैं, क्योंकि यह एक मजबूत सॉफ़्टवेयर का भ्रम पैदा करता है जो क्रैश नहीं होता है (विशेषताएं केवल काम करने के लिए रुक जाएंगी ,
Printer
ऑब्जेक्ट पर कतार में कतार में)।
क्या आप इनमें से कोई भी पसंद करते हैं या आपके पास इसे प्राप्त करने के अन्य तरीके हैं?
मैं वास्तव में इस बात से सहमत नहीं हूं कि एनवीआई विशिष्ट मामले में एक अच्छा समाधान है। प्रिंटर एक बेस क्लास था, लेकिन इससे पहले कि तारों को जोड़ना अच्छा होगा आवश्यकता स्पष्ट रूप से व्यर्थ है। अगर मैंने प्रिंटर से प्राप्त करने की आवश्यकता देखी, तो मैं उस समय फिर से प्रतिक्रिया करता। –