आपकी मुख्य गलती यह है कि आप अभी भी अधिक प्रक्रियात्मक शब्दों में सोच रहे हैं। यह एक व्यक्ति के रूप में आप की आलोचना के रूप में नहीं है, यह केवल एक अवलोकन है। अधिक कार्यात्मक शब्दों में सोचना समय और अभ्यास के साथ आता है, और इसलिए विधियाँ उपयोगी हैं और आपको कॉल करने के लिए सबसे स्पष्ट सही चीजों की तरह दिखती हैं। आपकी द्वितीयक छोटी सी गलती आपकी पद्धति के अंदर आपका वैकल्पिक निर्माण कर रही है। वैकल्पिक का अर्थ दस्तावेज़ में मदद करना है कि कुछ मूल्य वापस कर सकता है या नहीं। आपको कुछ नहीं मिल सकता है।
इसने आपको पूरी तरह से सुपाठ्य कोड लिखने का नेतृत्व किया है जो पूरी तरह से उचित प्रतीत होता है, लेकिन आपको विले ट्विन प्रलोभनों द्वारा फुसलाया गया जो कि मिलता है और isPresent है।
बेशक सवाल जल्दी बन जाता है "क्यों isPresent और वहाँ भी मिलता है?"
एक चीज जो यहां बहुत से लोगों को याद आती है, वह है Present () यह है कि यह कोई ऐसी चीज नहीं है जो नए कोड के लिए लोगों द्वारा पूरी तरह से बोर्ड पर लिखी जाती है कि कैसे गोश-डार उपयोगी लैंबडास हैं, और जो कार्यात्मक चीज को पसंद करते हैं।
हालांकि, यह हमें कुछ (दो) अच्छे, महान, दमकदार (?) लाभ देता है:
- यह नई विशेषताओं का उपयोग करने के लिए विरासत कोड के संक्रमण को आसान बनाता है।
- यह वैकल्पिक के सीखने की अवस्था को आसान बनाता है।
पहले वाला बल्कि सरल है।
कल्पना कीजिए कि आपके पास एक एपीआई है जो इस तरह दिखता है:
public interface SnickersCounter {
/**
* Provides a proper count of how many snickers have been consumed in total.
*/
public SnickersCount howManySnickersHaveBeenEaten();
/**
* returns the last snickers eaten.<br>
* If no snickers have been eaten null is returned for contrived reasons.
*/
public Snickers lastConsumedSnickers();
}
और आपके पास इस तरह का उपयोग करके एक विरासत वर्ग था (रिक्त स्थान भरें):
Snickers lastSnickers = snickersCounter.lastConsumedSnickers();
if(null == lastSnickers) {
throw new NoSuchSnickersException();
}
else {
consumer.giveDiabetes(lastSnickers);
}
सुनिश्चित करने के लिए एक आकस्मिक उदाहरण। लेकिन यहाँ मेरे साथ सहन करो।
Java 8 अब लॉन्च हो गया है और हम इसमें सवार होने के लिए हाथ-पांव मार रहे हैं। इसलिए हमारे द्वारा की जाने वाली चीजों में से एक यह है कि हम अपने पुराने इंटरफ़ेस को किसी ऐसी चीज़ से बदलना चाहते हैं जो ऑप्शनल लौटे। क्यों? क्योंकि जैसा कि किसी और ने पहले ही स्पष्ट रूप से उल्लेख किया है:
यह अनुमान लगाता है कि क्या कुछ शून्य हो सकता है या नहीं
यह पहले ही दूसरों द्वारा इंगित किया जा चुका है। लेकिन अब हमें एक समस्या है। कल्पना कीजिए कि हमारे पास (एक निर्दोष विधि पर alt + F7 हिट करते समय मुझे माफ करना), 46 स्थानों पर जहां इस पद्धति को अच्छी तरह से परीक्षण किए गए विरासत कोड में कहा जाता है जो अन्यथा एक उत्कृष्ट काम करता है। अब आपको इन सभी को अपडेट करना है।
यह वह जगह है जहाँ पर चमकता है।
क्योंकि अब: स्निकर्स lastSnickers = snickersCounter.lastConsumedSnickers (); if (null == lastSnickers) {फेंकिए नया NoSuchSnickersException (); } और {कंज्यूमर.गिवडायबिटीज (लास्टसनिकर्स); }
हो जाता है:
Optional<Snickers> lastSnickers = snickersCounter.lastConsumedSnickers();
if(!lastSnickers.isPresent()) {
throw new NoSuchSnickersException();
}
else {
consumer.giveDiabetes(lastSnickers.get());
}
और यह एक सरल परिवर्तन है जो आप नए जूनियर को दे सकते हैं: वह कुछ उपयोगी कर सकता है, और वह उसी समय कोडबेस का पता लगाने के लिए मिलेगा। विन-विन। सब के बाद, इस पैटर्न के लिए कुछ बहुत व्यापक है। और अब आपको लैम्ब्डा या कुछ भी उपयोग करने के लिए कोड को फिर से लिखना नहीं होगा। (इस विशेष मामले में यह तुच्छ होगा, लेकिन मैंने उन उदाहरणों को सोचना छोड़ दिया जहां पाठक के लिए एक अभ्यास के रूप में यह मुश्किल होगा।)
ध्यान दें कि इसका मतलब यह है कि आपने जिस तरह से किया है वह अनिवार्य रूप से विरासत में कोड के साथ सौदा करने का एक तरीका है बिना महंगा रीराइट किए। तो नए कोड के बारे में क्या?
ठीक है, आपके मामले में, जहाँ आप केवल कुछ प्रिंट करना चाहते हैं, आप बस करेंगे:
। SnickersCounter.lastConsumedSnickers () ifPresent (System.out :: println);
जो बहुत सरल है, और पूरी तरह से स्पष्ट है। वह बिंदु जो धीरे-धीरे सतह तक बुदबुदा रहा है, वह यह है कि वहाँ मौजूद मामलों को प्राप्त करने के लिए उपयोग किया जाता है () और isPresent ()। वे आपको इसके बारे में बहुत अधिक सोचने के बिना नए प्रकार का उपयोग करने के लिए यांत्रिक रूप से मौजूदा कोड को संशोधित करने देने के लिए हैं। इसलिए आप निम्न तरीकों से गुमराह हो रहे हैं:
- आप एक ऐसी विधि कह रहे हैं जो अशक्त हो सकती है। सही विचार यह होगा कि विधि शून्य हो जाती है।
- आप इस वैकल्पिक तरीके से निपटने के लिए विरासत बैंडैड विधियों का उपयोग कर रहे हैं, इसके बजाय स्वादिष्ट नए तरीकों का उपयोग करते हैं जिनमें लैंबडा काल्पनिकता होती है।
यदि आप वैकल्पिक को एक साधारण अशक्त-सुरक्षा जांच के रूप में उपयोग करना चाहते हैं, तो आपको जो करना चाहिए वह बस यह है:
new Optional.ofNullable(employeeServive.getEmployee())
.map(Employee::getId)
.ifPresent(System.out::println);
बेशक, यह दिखने में अच्छा लगता है:
employeeService.getEmployee()
.map(Employee::getId)
.ifPresent(System.out::println);
वैसे, जब तक यह आवश्यक नहीं है, मैं प्रति ऑपरेशन एक नई लाइन का उपयोग करने की सलाह देता हूं, ताकि पढ़ने में आसानी हो। सप्ताह के किसी भी दिन धड़कन को समझना और समझना आसान है।
यह निश्चित रूप से एक बहुत ही सरल उदाहरण है जहां यह सब कुछ समझना आसान है जिसे हम करने की कोशिश कर रहे हैं। यह हमेशा वास्तविक जीवन में यह सरल नहीं है। लेकिन ध्यान दें कि इस उदाहरण में, हम जो व्यक्त कर रहे हैं वह हमारे इरादे हैं। हम कर्मचारी को चाहते हैं, उसकी आईडी प्राप्त करें, और यदि संभव हो तो इसे प्रिंट करें। यह ऑप्शनल के साथ दूसरी बड़ी जीत है। यह हमें स्पष्ट कोड बनाने की अनुमति देता है। मैं यह भी सोचता हूं कि सामान बनाने का तरीका जो सामान बनाने का काम करता है ताकि आप इसे एक नक्शे पर फीड कर सकें, सामान्य तौर पर एक अच्छा विचार है।