2015-08-26 12 views
5

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

Null Object design pattern

+3

जावा 8 में, आप अतिरिक्त चेक किए बिना NullPointerExceptions से बचने के लिए वैकल्पिक का उपयोग कर सकते हैं। http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html – Stultuske

+0

अन्य भाषाओं जैसे सी # और सी ++ –

+2

@ मुहम्मद अहमसर जितना अधिक आप अनुभव करेंगे, उतना ही आपको पता चलेगा कि जितना अधिक आप महसूस करेंगे एक सुपर-फास्ट प्रोग्राम जो काम नहीं करता है या बग से भरा है, एक तेज़ पर्याप्त प्रोग्राम से भी बदतर है जो अच्छी तरह से काम करता है। सब कुछ प्रदर्शन और स्मृति पदचिह्न के बारे में नहीं है। बग से बचें और अधिक महत्वपूर्ण है। 'नल' कई बग का स्रोत है, और शून्य के लिए जांच अक्सर भूल जाती है। –

उत्तर

4

null के साथ पूरी समस्या यह है कि यदि आप null मान तक पहुंचने का प्रयास करते हैं तो यह एप्लिकेशन NullPointerException फेंक देगा और निरस्त करेगा।

इस अशक्त वस्तु डिजाइन पैटर्न में (अपने वास्तव में सिर्फ कारखाने डिजाइन dattern, एक ही पैटर्न नहीं) वर्ग NullXXX की संख्या को कम करने के लिए आप एक static final NullCustomer जो हमेशा लौटा दिया जाता है बना सकते हैं।

जावा 8 में आप Optional दृष्टिकोण का उपयोग यह बताने के लिए कर सकते हैं कि कोई फ़ंक्शन हमेशा मान वापस नहीं करता है। यह दृष्टिकोण आपको मनमानी नल वर्ग बनाने के लिए मजबूर नहीं करता है जो समग्र संरचना को प्रदूषित करता है (विचारों को उन शून्य वर्गों को फिर से प्रतिक्रिया देना पड़ सकता है)।

Eclipse और IntelliJ भी समय एनोटेशन @Nullable, @NonNull जो संकलक चेतावनी जब संभावित null वस्तुओं तक पहुँचने देने के संकलन प्रदान करते हैं। हालांकि, कई ढांचे को एनोटेट नहीं किया गया है। इसलिए IntelliJ स्थिर विश्लेषण के साथ discover those potential null accesses करने की कोशिश करता है। इस दृष्टिकोण के कम गोद लेने के अलावा इंटेलिजे और ग्रहण अपनी स्वयं की टिप्पणियों का उपयोग करते हैं (org.eclipse.jdt.annotation.NonNull, com.intellij.annotations.NotNull) कि वे संगत नहीं हैं। लेकिन, आप store the annotations outside of the code कर सकते हैं जो IntelliJ में काम करता है। ग्रहण भी भविष्य में इसे लागू करना चाहता है। समस्या यह है कि many frameworks providing this feature आपको कई अलग-अलग टिप्पणियां दे रहे हैं। JSR-305 था जो निष्क्रिय है। यह javax में एक एनोटेशन प्रदान करेगा। मुझे यह नहीं पता कि उन्होंने आगे क्यों नहीं धकेल दिया।

+0

बस में संशोधन करने के लिए इस "ग्रहण भविष्य में इस लागू करना चाहते हैं, भी": बाहरी एनोटेशन के लिए समर्थन ग्रहण मंगल ग्रह (4.5) के माध्यम से जारी की गई है। –

+0

एक और स्पष्टीकरण: "इंटेलीजे और ग्रहण के लिए अपने स्वयं एनोटेशन (org.eclipse.jdt.annotation.NonNull, com.intellij.annotations.NotNull) है कि उन संगत नहीं हैं का उपयोग करें"। इन एनोटेशन के भीतर केवल एक चीज है जो असंगत हो सकती है: '@ target'। जहाजों ग्रहण दो संस्करणों, org.eclipse.jdt.annotation_1.x 1.7 और नीचे के लिए ("घोषणा एनोटेशन"), और 1.8 और इसके बाद के संस्करण के लिए org.eclipse.jdt.annotation_2.x ("प्रकार एनोटेशन", जहां लक्ष्य 'है बहुत मजबूत जांच के लिए TYPE_USE')। इसके अलावा, एक्लिप्स को उचित रूप से परिभाषित शून्य एनोटेशन के किसी भी सेट का उपयोग करने के लिए कॉन्फ़िगर किया जा सकता है। –

0

इस पद्धति का मुख्य अंतर यह है (और शायद लाभ) स्पष्टता है। निम्न विधि परिभाषा के बारे में सोचें:

public static int length(String str); 

यह विधि दी गई स्ट्रिंग की लंबाई की गणना करती है। लेकिन तर्क null हो सकता है? विधि क्या करेगी? अपवाद फेंको? वापसी 0? वापसी -1? हम नहीं जानते।

कुछ आंशिक समाधान अच्छे जावा दस्तावेज़ लिखकर हासिल किया जा सकता है। अगला और थोड़ा बेहतर समाधान एनोटेशन जेएसआर 305 एनोटेशन @Nullable या @NotNullable का उपयोग कर रहा है, हालांकि डेवलपर द्वारा अनदेखा किया जा सकता है।

लेकिन आप अशक्त वस्तु पैटर्न (अमरूद या जावा 8 की जैसे वैकल्पिक) का उपयोग कर रहे अपने कोड ऐसा दिखाई देता है:

public static int length(Optional<String> str); 

तो डेवलपर वैकल्पिक में अपने स्ट्रिंग लपेटकर के बारे में परवाह चाहिए और इसलिए आपको उस कथन को समझता है शून्य हो सकता है वैकल्पिक से मूल्य प्राप्त करने का प्रयास जिसमें शून्य कारण अपवाद शामिल है जो नियमित null के साथ काम करते समय हमेशा नहीं होता है।

स्पष्ट रूप से आप सही हैं कि इस पैटर्न का उपयोग करने से कुछ अतिरिक्त CPU और स्मृति खपत होती है जो ज्यादातर मामलों में महत्वपूर्ण नहीं होती है।

+0

अशक्त वस्तु पैटर्न (https://en.wikipedia.org/wiki/Null_Object_pattern) वैकल्पिक के रूप में ही नहीं है। –

1

बजाय अशक्त वस्तु का उपयोग कर null का प्रमुख लाभ आप दोहराने के लिए कि क्या उस वस्तु वास्तव में null, विशेष रूप से सभी तरीकों कि उस वस्तु की आवश्यकता होती है में है की जांच के null का उपयोग कर रहा है। तो

Object o = Objects.requireNotNull(o); //Throws NullPointerException if o is indeed null. 

, यदि आप एक विधि है कि लगातार विभिन्न विधि में एक ही वस्तु पारित किया है, प्रत्येक विधि कि प्राप्त वस्तु नहीं है की जाँच करने की आवश्यकता होगी:

जावा 8 में, एक करना होगा इसका उपयोग करने से पहले शून्य।

तो, एक बेहतर दृष्टिकोण एक नल ऑब्जेक्ट, या Optional (जावा 8 और उच्चतर) होना है ताकि आपको हर समय शून्य जांच करने की आवश्यकता न हो। इसके बजाय एक होगा:

Object o = optional.get(); //Throws NullPointerException if internal value is indeed null. 
//Keep using o. 

नहीं (वास्तव में) शून्य जांच की आवश्यकता है। तथ्य यह है कि आपके पास Optional का अर्थ है कि आपके पास कोई मूल्य या कोई भी हो सकता है। क्योंकि यह आम तौर पर कुछ भी नहीं (आमतौर पर सभी तरीकों एक खाली विधि है) करता है तो (बाधाओं/अनुकूलन/आदि) के प्रदर्शन के बारे में चिंता करने की कोई जरूरत नहीं है

अशक्त वस्तुओं कोई साइड इफेक्ट है।

+0

तुम अब भी अगर वैकल्पिक रूप से मौजूद है जांच करने की जरूरत है, और एक NullPointerException अभी भी कुछ आप बचना चाहते हैं है। यह सिर्फ इसलिए है, क्योंकि यह एक वैकल्पिक है, अब यह स्पष्ट है कि यह अनुपस्थित हो सकता है। –

+0

@ जेबी निजेट वास्तव में। मैं हर बार 'शून्य' जांच करने की कमी पर बल देने की कोशिश कर रहा था। –

+0

अशक्त एनोटेशन के साथ आप एक @NonNull तर्क लेने के रूप में उन सभी तरीकों निर्दिष्ट करें। फिर कॉलर प्रश्न में स्थानीय चर पर एक शून्य जांच/जोर देगा और इस चर को सभी विधि कॉल में पास करेगा और सब अच्छा है। इसके अलावा: यह विधि कॉल के बारे में संभावित भ्रम से बचाता है, जो कुछ काम करने की उम्मीद है, वे प्रभावी रूप से नो-ऑप्स हो सकते हैं। –

0

मान लीजिए आप कुछ इस तरह है:

private SomeClass someField; 

void someMethod() { 
    // some other code 
    someField.method1(); 
    // some other code 
    someField.method2(); 
    // some other code 
    someField.method3(); 
} 

अब वैध उपयोग के मामलों जब someFieldnull हो सकता है देखते हैं कि लगता है और आप अपनी विधियां प्रारंभ नहीं करना चाहते हैं, लेकिन आप अन्य some other code पर अमल करना चाहते हैं विधि के खंड।

void someMethod() { 
    // do something 
    if (someField != null) { 
    someField.method1(); 
    } 
    // do something 
    if (someField != null) { 
    someField.method2(); 
    } 
    // do something 
    if (someField != null) { 
    someField.method3(); 
    } 
} 

खाली (कोई को-अप) के तरीकों के साथ अशक्त वस्तु का उपयोग कर हम बॉयलरप्लेट अशक्त चेकों से बचने के (और संभावना घटनाओं के सभी के लिए जाँच करता है जोड़ने के लिए भूल जाते हैं) द्वारा: आप के रूप में विधि को लागू करने की आवश्यकता होगी।

मुझे अक्सर ऐसी स्थिति में उपयोगी लगता है जब कुछ अतुल्यकालिक या वैकल्पिक रूप से प्रारंभ होता है।

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