किसी फ़ंक्शन को कॉल करने का यह तरीका एक बुरा अभ्यास है?


10

मेरे पास निम्नलिखित कोड हैं:

public void moveCameraTo(Location location){
    moveCameraTo(location.getLatitude(), location.getLongitude());
}

public void moveCameraTo(double latitude, double longitude){
    LatLng latLng = new LatLng(latitude, longitude);
    moveCameraTo(latLng);
}

public void moveCameraTo(LatLng latLng){
    GoogleMap googleMap =  getGoogleMap();
    cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, INITIAL_MAP_ZOOM_LEVEL);
    googleMap.moveCamera(cameraUpdate);
}

मुझे लगता है कि इस तरह से मैं यह जानने की जिम्मेदारी को खत्म करता हूं कि LatLngउदाहरण के लिए, एक अन्य कक्षा में क्या है ।

और फ़ंक्शन को कॉल करने से पहले आपको डेटा तैयार करने की आवश्यकता नहीं है।

तुम क्या सोचते हो?

क्या इस दृष्टिकोण का कोई नाम है? क्या यह वास्तव में एक बुरा अभ्यास है?


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

5
अपने लक्ष्य को छुपाने के लिए है, तो LatLngइस बात का ग्राहकों से Cameraवर्ग, तो आप शायद नहीं चाहते हो moveCameraTo(LatLng)जा रहा है public
बिट्सफ्लॉजिक

उत्तरों में दी गई सलाह के अलावा, यह YAGNI का उल्लेख करने के लिए एक अच्छी जगह की तरह लगता है। आपको इसकी आवश्यकता नहीं है। इससे पहले कि वहाँ एक अच्छा उपयोग के मामले है क्योंकि एपीआई तरीकों को परिभाषित न करें ... आप इसकी आवश्यकता नहीं है।
पैट्रिक ह्यूजेस

moveCameraToLocationऔर moveCameraTo/ के साथ कुछ भी गलत नहीं है moveCameraToCoords। निश्चित रूप से सभी समान नामों में स्थान / अव्यक्त / लंबे समय तक नहीं रहना चाहते हैं।
इंसाइडिन

जवाबों:


9

आप अपनी भाषाओं का उपयोग कर रहे हैं ओवरलोडिंग सुविधा का उपयोग करने के लिए कॉलर को वैकल्पिक तरीकों को हल करने के लिए स्थिति की जानकारी पर निर्भरता के तरीकों की पेशकश करते हैं। फिर आप कैमरे को अपडेट करने के शेष कार्य को हल करने के लिए किसी अन्य विधि को सौंप रहे हैं।

यहां कोड की गंध होगी यदि आप तरीकों को कॉल करने के तरीकों की श्रृंखला का विस्तार कर रहे हैं। लोकेशन लेने की विधि डबल लेने की विधि को कॉल करती है, जो लेटलिंग लेने की विधि को कॉल करती है जो अंत में कुछ ऐसा कहती है जो जानता है कि कैमरे को कैसे अपडेट किया जाए।

लंबी जंजीरें केवल उनकी सबसे कमजोर कड़ी के रूप में मजबूत होती हैं। श्रृंखला के प्रत्येक विस्तार से कोड के पदचिह्न में वृद्धि होती है जिसे काम करना पड़ता है या यह चीज टूट जाती है।

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

इसे इस तरह से करें और आप हर चीज का आधा हिस्सा तोड़े बिना ही निकाल सकते हैं।

विचार करें:

public void moveCameraTo(Location location){
    moveCameraTo( new LatLng(location) );
}

यह अक्षांश और देशांतर की LatLngसमस्या से निपटता है। लागत यह है कि यह LatLngचारों ओर का ज्ञान फैलाता है । यह महंगा लग सकता है, लेकिन मेरे अनुभव में यह आदिम जुनून के लिए एक बेहतर विकल्प है जो एक पैरामीटर ऑब्जेक्ट को स्थापित करने से बचता है जो आपके साथ चिपका हुआ है।

यदि Locationरिफैक्टेबल है, लेकिन LatLngऐसा नहीं है, तो इसे एक कारखाने में जोड़कर हल करने पर विचार करें Location:

moveCameraTo( location.ToLatLng() );

यह भी आदिम जुनून से बचा जाता है।


1
यह मेरे लिए बुरा नहीं लगता - यह वास्तव में उपभोक्ता के लिए सिर्फ एक सुविधा है। अगर यह 10 बार जंजीर में डाला गया या यदि उपभोक्ता को वास्तव में इन सभी विकल्पों की आवश्यकता नहीं है, तो मैं इसे कोड गंध कहूंगा।
mnnnz

1
लेकिन प्रत्येक फ़ंक्शन में LagLng या स्थान को LagLng में बदलने के लिए वैकल्पिक तर्क क्या है?
टाललोक-ईएस

@ Tlaloc-ES बेहतर है?
कैंडिड_ऑरेंज

@ टाललोक-ईएस "परिवर्तन" केवल एक बार होने की जरूरत है जब प्राइमेटिव डोमेन लॉजिक में लोड किए जा रहे हैं। यह तब होता है जब आप डीटीओ को डिस्क्राइब करते हैं। फिर, आपके सभी डोमेन तर्क पास LatLngया Locationऑब्जेक्ट्स को पास करने के लिए मिलते हैं। आप दोनों के बीच के संबंध को दिखा सकते हैं New LatLng(Location)या Location.toLatLng()यदि आपको एक से दूसरे में जाने की आवश्यकता है।
बिट्सफ्लॉजिक

1
@ टाललोक -ईएस संबंधित पढ़ना: फ्लैगएरगमेंट मार्टिन फावलर द्वारा। "पेचीदा कार्यान्वयन" अनुभाग पढ़ें।
Marc.2377

8

आपके समाधान के साथ कुछ भी गलत नहीं है।

लेकिन मेरी व्यक्तिगत प्राथमिकता यह होगी कि वे तरीके उतने उपयोगी नहीं हैं। और जिस भी वस्तु से वे भाग रहे हैं उसके इंटरफ़ेस को जटिल करें।

यह void moveCameraTo(double latitude, double longitude)वास्तव में कोड को सरल नहीं करता है, क्योंकि मुझे कोई समस्या नहीं दिखती है बस moveCameraTo(new LatLng(latitude, longitude));इसमें जगह है। इस पद्धति से भी आदिम जुनून की बू आती है।

void moveCameraTo(Location location)बेहतर साबित द्वारा हल किया जा सकता है Location.ToLatLng()विधि और बुला moveCameraTo(location.ToLatLng())

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

मुझे लगता है कि इस तरह से मैं यह जानने की जिम्मेदारी को खत्म करता हूं कि उदाहरण के लिए, एक अन्य कक्षा में एक लैटलिंग क्या है।

मुझे कोई कारण नहीं दिखता कि यह समस्या क्यों होगी। जब तक आपका कोड संदर्भ वर्ग जिसमें शामिल है void moveCameraTo(LatLng latLng), यह अभी भी अप्रत्यक्ष रूप से निर्भर करता है LatLng। भले ही वह वर्ग कभी प्रत्यक्ष रूप से तात्कालिक न हो।

और फ़ंक्शन को कॉल करने से पहले आपको डेटा तैयार करने की आवश्यकता नहीं है।

मुझे समझ नहीं आ रहा है कि आपका क्या मतलब है। यदि इसका अर्थ है नई आवृत्ति बनाना या कक्षाओं को एक से दूसरे में बदलना, तो मुझे इससे कोई समस्या नहीं है।

इसके बारे में सोचते हुए, मुझे लगता है कि मैं जो कह रहा हूं वह भी .NET के एपीआई डिजाइन द्वारा समर्थित है। ऐतिहासिक रूप से, बहुत सारे .NET वर्ग ने विभिन्न मापदंडों के साथ बहुत सारे ओवरलोड होने के अपने दृष्टिकोण का पालन किया, और अंदर सरल रूपांतरण। लेकिन इससे पहले कि विस्तार के तरीके मौजूद थे। अधिक आधुनिक .NET कक्षाएं अपने स्वयं के एपीआई में अधिक हल्के वजन वाली होती हैं और यदि कोई पैरामीटर ओवरलोड के साथ कोई विधि है, तो उन्हें विस्तार विधियों के रूप में प्रदान किया जाता है। पुराना उदाहरण NLog ILogger है जिसमें लॉग करने के लिए लिखने के लिए दर्जनों ओवरलोड हैं। उसकी तुलना नए Microsoft.Extensions.Logging.ILogger से करें जिसमें कुल 3 विधियाँ हैं (और केवल 1 यदि आप लॉगिंग को स्वयं ही गिन लें)। लेकिन विस्तार विधियों के रूप में बहुत से सहायक और विभिन्न पैरामीरिजेशन हैं ।

मुझे लगता है कि इस उत्तर से पता चलता है कि कुछ भाषाओं में इस तरह के डिजाइन बनाने के उपकरण होंगे। मुझे ज्यादा जावा पता नहीं है, इसलिए मुझे यकीन नहीं है कि कोई समकक्ष होगा। लेकिन यहां तक ​​कि सादे स्थिर तरीकों का उपयोग करना एक विकल्प हो सकता है।


यकीन नहीं हो रहा है, लेकिन मैं अपने आप को एक प्रतिस्पर्धी होने के बावजूद इस जवाब के लिए निहित करता हूं। मुझे लगता है कि आप इस बिंदु को बेहतर बनाने में सफल रहे। मेरी एकमात्र प्रतिक्रिया यह याद रखना होगा कि इस मुद्दे से निपटने वाला हर कोई .NET पर नहीं है। +1
कैंडिड_ओरेंज

@candied_orange राइट। अब जब मैं ओपी के सवाल पर बेहतर लग रहा हूं, तो यह सी # की तुलना में जावा की तरह दिखता है।
जश्न

मुझे लगता है कि वास्तव moveCameraTo(new LatLng(latitude, longitude));में इस परियोजना के किसी भी स्थान पर उपयोग में कोई समस्या नहीं है , लेकिन मुझे लगता है कि अधिक स्पष्ट उपयोग सीधे MoveCametaTo (latLng) है, जावा में एक फाइल की तरह है, आप स्ट्रिंग की तरह पथ पारित कर सकते हैं, या एक पथ वर्ग की तरह
Tlaloc-ES

1

मुझे यकीन नहीं है कि इसके लिए उचित नाम क्या है, अगर यह एक है, लेकिन यह अच्छा अभ्यास है। आप एकाधिक अधिभार को उजागर करते हैं, जिससे कॉलिंग वर्ग यह निर्धारित कर सकता है कि कौन सा पैरामीटर सेट करना चाहता है। जैसा कि आप कहते हैं, एक अन्य वर्ग यह नहीं जान सकता है कि कोई LatLngवस्तु क्या है, लेकिन इसका पता हो सकता है Location

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


1

यदि आप किसी प्रकार की विधियों का उपयोग करने का मन बनाते हैं, तो यह केवल विधि-अधिभार सुविधा है, यह अच्छा है।

लेकिन यह जानने की जिम्मेदारी खत्म नहीं हुई है कि लाटलिंग क्या है । क्योंकि आप इनिशियलाइज़ कर रहे हैं LatLng latLng = new LatLng(latitude, longitude)। यह पूरी तरह से निर्भरता है LatLng। (यह समझने के लिए कि प्रारंभ करना निर्भरता समस्या क्यों है, आप निर्भरता इंजेक्शन की जांच कर सकते हैं ) अतिभारित विधि बनाने से केवल उन ग्राहकों को मदद मिलती है जो परवाह नहीं करते हैं LatLng। यदि आप यह मतलब है, यह भी अच्छा है, लेकिन मुझे नहीं लगता कि यह एक दृष्टिकोण है। यह ग्राहकों के लिए सिर्फ कई सेवा विधियां हैं।

तो, आपकी वास्तुकला को डिजाइन करने के लिए दो विकल्प हैं:

  1. कई अतिभारित विधि बनाएं और उन्हें क्लाइंट को प्रदान करें।
  2. इंटरफ़ेस या ठोस वर्ग के रूप में पैरामीटर (ओं) की आवश्यकता वाले कुछ अतिभारित तरीके बनाएँ।

मैं उन तरीकों को बनाने से दूर भागता हूं, जिन्हें पैरामीटर (विकल्प 1) के रूप में आदिम प्रकार की आवश्यकता होती है। क्योंकि यदि आपका व्यवसाय कई बार बदलता है और आपको विधि पैरामीटर खेलने की आवश्यकता होती है, तो सभी कॉलर फ़ंक्शन को बदलना और कार्यान्वित करना वास्तव में कठिन है।

इसके बजाय, इंटरफेस (डिपेंडेंसी इंजेक्शन) का उपयोग करें। यदि आपको लगता है कि यह लागत है और अधिक समय लगता है, तो कक्षाओं का उपयोग करें और उनके मैपर एक्सटेंशन के तरीके (विकल्प 2) प्रदान करें।

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