क्या एक संपत्ति खराब फॉर्म से एक अपवाद फेंक रहा है?


15

मैं हमेशा इस मानसिकता का रहा हूं कि गुण (यानी, उनके सेट / ऑपरेशन मिलते हैं) तेज / तत्काल और असफल-मुक्त होने चाहिए। प्रॉपर्टी पाने या सेट करने के लिए आपको कभी भी कोशिश नहीं करनी चाहिए।

लेकिन मैं कुछ वस्तुओं के गुणों पर भूमिका-आधारित सुरक्षा लागू करने के कुछ तरीके देख रहा हूं। उदाहरण के लिए एक कर्मचारी। संपत्ति की संपत्ति। मेरे द्वारा चलाए गए कुछ समाधानों को दूसरों ने आज़माया है (विशेष रूप से एओपी उदाहरण यहाँ है ) यदि अपवाद को सही अनुमति नहीं है तो एक अपवाद को शामिल करना शामिल है - लेकिन यह एक व्यक्तिगत नियम के खिलाफ जाता है जो मैंने किया है अब लंबे समय के लिए।

तो मैं पूछता हूं: क्या मैं गलत हूं? क्या चीजें बदल गई हैं? क्या यह स्वीकार किया गया है कि संपत्तियों को अपवाद फेंकने में सक्षम होना चाहिए?


1
यह StackOverflow पर एक ही सवाल और अधिक ध्यान और इतने के सही उत्तर मिल गया।
रोमन स्टार्कोव

जवाबों:


14

जब आप किसी संपत्ति का मूल्य निर्धारित करते हैं, तो एक अमान्य मूल्य पर एक अपवाद फेंकना ठीक है

एक संपत्ति का मूल्य प्राप्त करना (लगभग) कभी भी अपवाद नहीं फेंकना चाहिए

भूमिका-आधारित पहुंच के लिए, विभिन्न / डम्बर इंटरफेस या facades का उपयोग करें; लोगों को वे चीजें न दें जो उनके पास नहीं हैं!


5

मैं इसे ज्यादातर खराब फॉर्म मानता हूं लेकिन Microsoft कभी-कभी अपवादों का उपयोग करने की सलाह देता है। एक अच्छा उदाहरण अमूर्त संपत्ति Stream.Length है । जैसा कि दिशा-निर्देश चलते हैं, मैं गेटर्स पर साइड इफेक्ट से बचने और बसने वालों पर साइड इफेक्ट को सीमित करने के साथ अधिक चिंतित हूं।


4

मैं निश्चित रूप से यह तर्क दूंगा कि अगर आपको प्रॉपर्टी सेटर या गेट्टर से अपवाद फेंकने की आवश्यकता महसूस होती है तो डिजाइन में कोई दोष है।

एक संपत्ति एक अमूर्तता है जो एक ऐसी चीज का प्रतिनिधित्व करती है जो सिर्फ एक मूल्य है । और आपको इस डर के बिना एक मूल्य निर्धारित करने में सक्षम होना चाहिए कि ऐसा करने से कोई अपवाद नहीं हो सकता है। *

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

पहले से ही एक अलग जवाब में उल्लिखित एक उदाहरण Stream.Positionसंपत्ति है। यह दुष्प्रभाव पैदा करता है, और अपवाद फेंक सकता है। लेकिन यह संपत्ति सेटर मूल रूप से केवल एक आवरण है जिसके चारों ओर Stream.Seekआप इसके बजाय कॉल कर सकते हैं।

व्यक्तिगत रूप से, मेरा मानना ​​है कि स्थिति एक लेखन योग्य संपत्ति नहीं होनी चाहिए।

एक अन्य उदाहरण जहां आपको संपत्ति सेटर से अपवाद फेंकने के लिए लुभाया जा सकता है, वह डेटा के सत्यापन में है:

public class User {
    public string Email {
        get { return _email; }
        set { 
            if (!IsValidEmail(value)) throw InvalidEmailException(value);
            _email = value;
        }
    }

लेकिन इस समस्या का एक बेहतर समाधान है। एक मान्य ईमेल पते का प्रतिनिधित्व करने वाला एक प्रकार पेश करें:

public class Email {
    public Email(string value) {
        if (!IsValidEmail(value)) throw new InvalidEmailException(value);
        ...
    }
    ...
}

public class User {
    public Email Email { get; set; }
}

Emailवर्ग सुनिश्चित है कि यह है कि एक मान्य ईमेल पता नहीं है एक मूल्य को रोक नहीं सकते, और वर्गों है कि दुकान ईमेल की जरूरत उन्हें मान्य का कर्तव्य से मुक्त कर रहे हैं।

यह उच्च सामंजस्य (अच्छे सॉफ़्टवेयर डिज़ाइन का एक संकेतक) की ओर भी जाता है - एक ईमेल पता क्या है और इसे कैसे मान्य किया जाता है, इसके बारे में ज्ञान केवल Emailकक्षा में मौजूद है , जिसमें केवल यही चिंता है।

* ObjectDisposedException एकमात्र वैध अपवाद है (जिसका कोई उद्देश्य नहीं है) मैं इस समय सोच सकता हूं।


2

मुझे पता है कि आपका प्रश्न .NET के लिए विशिष्ट है , लेकिन चूंकि C # जावा के साथ कुछ इतिहास साझा करता है, इसलिए मुझे लगा कि आपकी रुचि हो सकती है। मैं किसी भी तरह से यह नहीं कह रहा हूं कि क्योंकि जावा में कुछ किया जाता है, इसे सी # में किया जाना चाहिए। मुझे पता है कि दोनों बहुत अलग हैं, विशेष रूप से कैसे सी # में गुणों के लिए भाषा-स्तर में बहुत सुधार हुआ है। मैं सिर्फ कुछ संदर्भ और परिप्रेक्ष्य दे रहा हूं।

से JavaBeans विनिर्देश :

विवश गुण कभी-कभी जब संपत्ति में परिवर्तन होता है तो कुछ अन्य सेम परिवर्तन को मान्य करना चाहते हैं और इसे अस्वीकार कर सकते हैं यदि यह अनुचित है। हम ऐसे गुणों का उल्लेख करते हैं जो विवश गुणों के रूप में इस तरह की जाँच से गुजरते हैं। जावा बीन्स में, PropertyVetoException का समर्थन करने के लिए विवश संपत्ति सेटर विधियों की आवश्यकता होती है। अद्यतन किए गए प्रयासों के लिए विवश संपत्ति के उपयोगकर्ताओं के लिए यह दस्तावेज़ वीटो हो सकते हैं। तो एक साधारण विवश संपत्ति की तरह लग सकता है:

PropertyType getFoo();
void setFoo(PropertyType value) throws PropertyVetoException;

कृपया नमक के दाने के साथ यह सब लें। JavaBeans विनिर्देश पुराना है, और C # गुण (IMO) "नामकरण परंपरा" पर आधारित एक बहुत बड़ा सुधार है जो जावा के पास है। मैं बस थोड़ा सा संदर्भ देने की कोशिश कर रहा हूं, बस!


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

2

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

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


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

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

1

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

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


0

हालाँकि बहुत कुछ इस संदर्भ पर निर्भर करेगा कि मैं आम तौर पर गुणों में किसी भी प्रकार के तोड़-फोड़ वाले तर्क (अपवादों को शामिल) करने से बचूँगा। केवल एक उदाहरण के रूप में, बहुत सी चीजें हैं जो आप (या कुछ पुस्तकालय जो आप उपयोग कर रहे हैं) कर सकते हैं, जो संपत्तियों पर पुनरावृति करने के लिए प्रतिबिंब का उपयोग कर सकते हैं, जिसके परिणामस्वरूप आप डिजाइन-समय पर अनुमान नहीं लगा सकते हैं।

मैं आमतौर पर कहता हूं, क्योंकि कुछ समय हो सकता है जब आप बिल्कुल, निश्चित रूप से, परिणामों के बारे में बहुत अधिक चिंता किए बिना कुछ ब्लॉक करना चाहते हैं। सुरक्षा मुझे लगता है कि वहाँ क्लासिक मामला होगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.