मैं बूलियन क्लीयर के साथ कॉल कैसे कर सकता हूं? बुलियन ट्रैप


76

जैसा कि @ benjamin-gruenbaum द्वारा टिप्पणियों में नोट किया गया है, इसे बुलियन ट्रैप कहा जाता है:

कहो मेरे पास एक फंक्शन है ऐसा

UpdateRow(var item, bool externalCall);

और मेरे नियंत्रक में, वह मान externalCallहमेशा TRUE रहेगा। इस फ़ंक्शन को कॉल करने का सबसे अच्छा तरीका क्या है? मैं आमतौर पर लिखता हूं

UpdateRow(item, true);

लेकिन मैं अपने आप से पूछता हूं, क्या मुझे एक बूलियन घोषित करना चाहिए, बस यह इंगित करने के लिए कि 'सही' मूल्य क्या है? आप फ़ंक्शन की घोषणा को देखकर जान सकते हैं, लेकिन यह स्पष्ट रूप से तेज़ और स्पष्ट है यदि आपने कुछ ऐसा देखा है

bool externalCall = true;
UpdateRow(item, externalCall);

पीडी: यकीन नहीं अगर यह सवाल वास्तव में यहाँ फिट बैठता है, अगर यह नहीं है, तो मुझे इस बारे में अधिक जानकारी कहाँ से मिल सकती है?

PD2: मैंने किसी भी भाषा को टैग नहीं किया क्योंकि मुझे लगा कि यह बहुत सामान्य समस्या है। वैसे भी, मैं सी # के साथ काम करता हूं और सी # के लिए स्वीकृत जवाब काम करता है



11
यदि आप बीजीय डेटा प्रकारों के समर्थन के साथ एक भाषा का उपयोग कर रहे हैं, तो मैं बूलियन के बजाय एक नए विज्ञापन की बहुत सलाह दूंगा। data CallType = ExternalCall | InternalCallउदाहरण के लिए हैसेल में।
फ़िलिप हाग्लंड

6
मुझे लगता है कि एनम ठीक उसी उद्देश्य को भरेंगे; बुलियन के लिए नाम प्राप्त करना, और थोड़ा प्रकार की सुरक्षा।
फिलिप हगलुंड

2
मैं असहमत हूं कि अर्थ को इंगित करने के लिए बूलियन घोषित करना "स्पष्ट रूप से स्पष्ट" है। पहले विकल्प के साथ, यह स्पष्ट है कि आप हमेशा सही होंगे। दूसरे के साथ, आपको जांचना होगा (चर को परिभाषित कहां किया गया है? क्या इसका मूल्य बदल गया है?)। ज़रूर, यह समस्या नहीं है यदि दो लाइनें एक साथ हैं ... लेकिन कोई यह तय कर सकता है कि उनके कोड को जोड़ने के लिए सही जगह दो लाइनों के बीच है। होता है!
एजेपेरेस

बूलियन घोषित करना क्लीनर नहीं है, स्पष्ट है कि यह सिर्फ एक कदम पर कूद रहा है, जो प्रश्न में विधि के प्रलेखन को देख रहा है। यदि आप हस्ताक्षर जानते हैं, तो नया स्थिरांक जोड़ना कम स्पष्ट है।
insidesin

जवाबों:


154

हमेशा एक सही समाधान नहीं होता है, लेकिन आपके पास चुनने के लिए कई विकल्प हैं:

  • यदि आपकी भाषा में उपलब्ध है, तो तर्कों का उपयोग करें । यह बहुत अच्छी तरह से काम करता है और इसमें कोई खास कमी नहीं है। कुछ भाषाओं में, किसी भी तर्क को एक नामित तर्क के रूप में पारित किया जा सकता है, जैसे updateRow(item, externalCall: true)( C # ) या update_row(item, external_call=True)(पायथन)।

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

  • बेहतर नामों के साथ, अपने सार्वजनिक इंटरफ़ेस के लिए अलग-अलग कार्यों का उपयोग करें । नाम में paremeter मान डालकर, नामित मापदंडों का अनुकरण करने का यह एक और तरीका है।

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

  • एक एनम का उपयोग करें । बूलियन्स के साथ समस्या यह है कि उन्हें "सच" और "गलत" कहा जाता है। इसलिए, इसके बजाय बेहतर नाम (जैसे enum CallType { INTERNAL, EXTERNAL }) के साथ एक प्रकार का परिचय दें । अतिरिक्त लाभ के रूप में, यह आपके प्रोग्राम की सुरक्षा को बढ़ाता है (यदि आपकी भाषा अलग-अलग प्रकार से लागू होती है)। एनम का दोष यह है कि वे आपके सार्वजनिक रूप से दिखाई देने वाले API में एक प्रकार जोड़ते हैं। विशुद्ध रूप से आंतरिक कार्यों के लिए, यह कोई मायने नहीं रखता है और enums में कोई महत्वपूर्ण कमियां नहीं हैं।

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

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


7
मैंने अभी सीखा कि "नामित तर्क" मौजूद हैं। मुझे लगता है कि यह अब तक का सबसे अच्छा सुझाव है। यदि आप उस विकल्प पर थोड़ा विस्तार कर सकते हैं (ताकि अन्य व्यक्तियों को इसके बारे में बहुत अधिक Google की आवश्यकता न हो) तो मैं इस उत्तर को स्वीकार करूंगा। इसके अलावा अगर आप कर सकते हैं तो प्रदर्शन पर कोई संकेत ... धन्यवाद
मारियो गार्सिया

6
एक चीज जो शॉर्ट स्ट्रिंग्स के साथ समस्याओं को कम करने में मदद कर सकती है, वह है स्ट्रिंग मानों के साथ स्थिरांक का उपयोग करना। @MarioGarcia पर विस्तार करने के लिए बहुत कुछ नहीं है। इसके अलावा जो यहां बताया गया है, उसमें से अधिकांश विवरण विशेष भाषा पर निर्भर करेगा। क्या कुछ विशेष था जिसे आप यहाँ उल्लेखित देखना चाहते हैं?
jpmc26

8
उन भाषाओं में जहां हम एक विधि के बारे में बात कर रहे हैं और enum एक वर्ग के लिए स्कोप किया जा सकता है मैं आमतौर पर एक एनम का उपयोग करता हूं। यह पूरी तरह से स्व दस्तावेजीकरण है (कोड की एकल पंक्ति में जो एनम प्रकार की घोषणा करता है, इसलिए यह हल्का भी है), पूरी तरह से नग्न बूलियन के साथ बुलाया जाने से विधि को रोकता है, और सार्वजनिक एपीआई पर प्रभाव नगण्य है (पहचानकर्ताओं के बाद से) वर्ग के लिए scoped हैं)।
द्वैदबक

4
इस भूमिका में स्ट्रिंग्स का उपयोग करने की एक और कमी यह है कि आप अपनी वैधता की गणना, एनम के विपरीत संकलन समय पर नहीं कर सकते हैं।
रुस्लान

32
एनम विजेता है। सिर्फ इसलिए कि एक पैरामीटर में केवल दो संभावित राज्यों में से एक हो सकता है, इसका मतलब यह नहीं है कि यह स्वचालित रूप से एक बूलियन होना चाहिए।
पीट

39

सही समाधान यह है कि आप क्या सुझाव देते हैं, लेकिन इसे लघु-पहलू में पैकेज करें:

void updateRowExternally() {
  bool externalCall = true;
  UpdateRow(item, externalCall);
}

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


8
क्या यह एनकैप्सुलेशन वास्तव में इसके लायक है जब मैं केवल अपने नियंत्रक में एक बार उस कवक को बुलाता हूं?
मारियो गार्सिया

14
हाँ। हाँ यही है। कारण, जैसा कि मैंने ऊपर लिखा है, यह है कि लागत (एक फ़ंक्शन कॉल) लाभ की तुलना में छोटा है (आप डेवलपर समय की एक सामान्य राशि बचाते हैं क्योंकि किसी को कभी भी यह नहीं देखना trueपड़ता है कि क्या होता है।) भले ही यह सार्थक हो। सीपीयू समय सस्ता होने के बाद से डेवलपर समय की बचत के रूप में ज्यादा सीपीयू समय खर्च होता है।
काइलिन फोथ

8
इसके अलावा किसी भी सक्षम अनुकूलक को आपके लिए इनलाइन करने में सक्षम होना चाहिए ताकि आपको अंत में कुछ भी खोना न पड़े।
firedraco

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

6
मुझे लगता है UpdateRow(item, true /*external call*/);कि क्लीनर होगा, उन भाषाओं में जो उस वाक्यविन्यास को अनुमति देते हैं। एक टिप्पणी लिखने से बचने के लिए एक अतिरिक्त फ़ंक्शन के साथ अपने कोड को ब्लोट करना एक साधारण मामले के लिए इसके लायक नहीं लगता है। हो सकता है कि इस फ़ंक्शन के लिए बहुत सारे अन्य आर्गन्स थे, और / या कुछ बरबाद + मुश्किल कोड के आसपास, यह अधिक अपील करना शुरू कर देगा। लेकिन मुझे लगता है कि अगर आप डिबगिंग कर रहे हैं, तो आप रैपर फ़ंक्शन को देखने के लिए जा रहे हैं कि यह क्या करता है, और यह याद रखना होगा कि लाइब्रेरी API के आसपास कौन से फ़ंक्शंस पतले रैपर हैं, और जिनमें वास्तव में कुछ तर्क हैं।
पीटर कॉर्डेस

25

कहो कि मेरे पास UpdateRow (var item, bool externalCall) जैसा एक फ़ंक्शन है;

आपके पास इस तरह का एक समारोह क्यों है?

किन परिस्थितियों में आप इसे अलग-अलग मूल्यों पर सेट किए गए एक्सटर्नल कॉल तर्क के साथ कहेंगे?

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

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


6
मैं सहमत हूँ। और केवल अन्य पाठकों के लिए बनाए जा रहे बिंदु को हथौड़ा करने के लिए, सभी कॉलर्स का विश्लेषण किया जा सकता है, जो या तो सही, गलत या एक चर पारित करेंगे। यदि उत्तरार्द्ध में से कोई नहीं पाया जाता है तो मैं बूलियन के साथ एक से अधिक दो अलग-अलग तरीकों (w / o बूलियन) के लिए बहस करूँगा - यह एक YAGNI तर्क है कि बूलियन अप्रयुक्त / आवश्यक जटिलता का परिचय देता है। यहां तक ​​कि अगर कुछ कॉलर्स वैरिएबल से गुजर रहे हैं, तो मैं अभी भी (बुलियन) को पैरामीटर-मुक्त संस्करण प्रदान कर सकता हूं ताकि कॉलर्स को एक निरंतर पास करने के लिए उपयोग किया जा सके - यह सरल है, जो अच्छा है।
एरिक Eidt

18

हालांकि मैं मानता हूं कि पठनीयता और मूल्य-सुरक्षा दोनों को लागू करने के लिए एक भाषा सुविधा का उपयोग करना आदर्श है, आप एक व्यावहारिक दृष्टिकोण का विकल्प भी चुन सकते हैं : कॉल-टाइम टिप्पणियां। पसंद:

UpdateRow(item, true /* row is an external call */);

या:

UpdateRow(item, true); // true means call is external

या (ठीक है, जैसा कि फ्रैक्स ने सुझाव दिया है):

UpdateRow(item, /* externalCall */true);

1
नीचा दिखाने का कोई कारण नहीं। यह पूरी तरह से मान्य सुझाव है।
सनकैट २२

<3 @ Suncat2000 की सराहना करें!
बिशप

11
ए (संभावित रूप से बेहतर) वैरिएंट सिर्फ सादा तर्क नाम रख रहा है, जैसे UpdateRow(item, /* externalCall */ true )। पूर्ण-वाक्य टिप्पणी पार्स करने के लिए बहुत कठिन है, यह वास्तव में ज्यादातर शोर है (विशेष रूप से दूसरा संस्करण, जो कि तर्क के साथ बहुत शिथिल है)।
फ्राक्स

1
यह अब तक का सबसे उपयुक्त उत्तर है। यह ठीक वही है जो टिप्पणियों के लिए अभिप्रेत है।
प्रहरी

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

11
  1. आप अपने बूल को 'नाम' दे सकते हैं। नीचे एक OO भाषा के लिए एक उदाहरण है (जहाँ इसे कक्षा में प्रदान किया जा सकता है UpdateRow()), हालाँकि इस अवधारणा को स्वयं किसी भी भाषा में लागू किया जा सकता है:

    class Table
    {
    public:
        static const bool WithExternalCall = true;
        static const bool WithoutExternalCall = false;
    

    और कॉल साइट में:

    UpdateRow(item, Table::WithExternalCall);
    
  2. मेरा मानना ​​है कि आइटम # 1 बेहतर है, लेकिन यह फ़ंक्शन का उपयोग करते समय उपयोगकर्ता को नए चर का उपयोग करने के लिए मजबूर नहीं करता है। यदि आपके लिए प्रकार की सुरक्षा महत्वपूर्ण है, तो आप एक enumप्रकार बना सकते हैं और UpdateRow()इसके बजाय इसे स्वीकार कर सकते हैं bool:

    UpdateRow(var item, ExternalCallAvailability ec);

  3. आप फ़ंक्शन के नाम को किसी तरह से संशोधित कर सकते हैं कि यह boolपैरामीटर के अर्थ को बेहतर ढंग से दर्शाता है। बहुत निश्चित नहीं लेकिन शायद:

    UpdateRowWithExternalCall(var item, bool externalCall)


8
# 3 को अब पसंद न करें यदि आप फ़ंक्शन को कॉल करते हैं externalCall=false, तो इसका नाम बिल्कुल नहीं है। बाकी आपका जवाब अच्छा है।
को ऑर्बिट में लाइटनेस दौड़

माना। मुझे बहुत यकीन नहीं था लेकिन यह किसी अन्य फ़ंक्शन के लिए एक व्यवहार्य विकल्प हो सकता है। मैं
१urg ’

@LightnessRacesinOrbit वास्तव में। इसके लिए जाना ज्यादा सुरक्षित है UpdateRowWithUsuallyExternalButPossiblyInternalCall
एरिक डुमिनील

@ एरिकड्यूमिनिल: स्पॉट ऑन ric
ऑर्बिट में

10

एक अन्य विकल्प जो मैंने अभी तक यहां नहीं पढ़ा है वह है: एक आधुनिक आईडीई का उपयोग करें।

उदाहरण के लिए IntelliJ विचार विधि में चर आप यदि आप के रूप में एक शाब्दिक खासकर गुज़रते रहे कॉल कर रहे हैं की चर नाम प्रिंट trueया nullया username + “@company.com। यह एक छोटे से फ़ॉन्ट में किया जाता है इसलिए यह आपकी स्क्रीन पर बहुत अधिक स्थान नहीं लेता है और वास्तविक कोड से बहुत अलग दिखता है।

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

मेरे परीक्षण सेटअप के भाग का संशोधित उदाहरण: यहाँ छवि विवरण दर्ज करें


5
यह केवल तभी सच होगा जब आपकी टीम के सभी लोगों ने केवल आपके कोड को पढ़ने के लिए एक IDE का उपयोग किया हो। गैर-आईडीई संपादकों की व्यापकता के बावजूद, आपके पास कोड समीक्षा टूल, स्रोत नियंत्रण उपकरण, स्टैक ओवरफ्लो प्रश्न आदि भी हैं, और यह महत्वपूर्ण है कि कोड उन संदर्भों में भी पठनीय बना रहे।
डैनियल प्राइडेन

@DanielPryden यकीन है, इसलिए मेरी और आपके सहयोगियों की टिप्पणी। कंपनियों में मानक आईडीई होना आम बात है। अन्य उपकरणों के लिए, मैं तर्क देता हूं कि यह पूरी तरह से संभव है कि इस प्रकार के उपकरण भी भविष्य में इस या इच्छाशक्ति का समर्थन करते हैं, या यह कि वे तर्क बस लागू नहीं होते हैं (जैसे कि 2 व्यक्ति जोड़ी प्रोग्रामिंग टीम के लिए)
सेबेस्टियन वैन डेन ब्रोक

2
@ सेबेस्टियन: मुझे नहीं लगता कि मैं सहमत हूं। एकल डेवलपर के रूप में भी, मैं नियमित रूप से Git diffs में अपना कोड पढ़ता हूं। Git कभी भी एक ही तरह के संदर्भ-जागरूक विज़ुअलाइज़ेशन को करने में सक्षम नहीं होने वाला है जो एक IDE कर सकता है, और न ही। कोड लिखने में मदद करने के लिए मैं एक अच्छे IDE के उपयोग के लिए हूँ, लेकिन आपको कभी भी IDE का उपयोग उस कोड को लिखने के बहाने के रूप में नहीं करना चाहिए जो आपने इसके बिना लिखा होगा।
डैनियल प्रीडन

1
@DanielPryden मैं बेहद मैला कोड लिखने की वकालत नहीं कर रहा हूँ। यह एक श्वेत और श्याम स्थिति नहीं है। ऐसे मामले हो सकते हैं जहां अतीत में एक विशिष्ट स्थिति के लिए आप बूलियन के साथ एक फ़ंक्शन लिखने के पक्ष में 40% होंगे और 60% नहीं और आपने इसे समाप्त नहीं किया। हो सकता है कि अच्छे आईडीई समर्थन के साथ अब शेष राशि 55% हो, जैसे कि यह लिखना और 45% नहीं। और हाँ, आपको अभी भी IDE के बाहर इसे पढ़ने की आवश्यकता हो सकती है, इसलिए यह सही नहीं है। लेकिन यह अभी भी एक विकल्प के खिलाफ एक वैध व्यापार-बंद है, जैसे कोड को स्पष्ट करने के लिए किसी अन्य विधि या गणना को जोड़ना।
सेबेस्टियन वैन डेन ब्रोक

6

2 दिन और किसी ने बहुरूपता का उल्लेख नहीं किया?

target.UpdateRow(item);

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

वह करें और यह निर्माण समस्या का हिस्सा बन जाए। जिसे कई तरह से हल किया जा सकता है। यहां एक है:

Target xyzTargetFactory(TargetBuilder targetBuilder) {
    return targetBuilder
        .connectionString("some connection string")
        .table("table_name")
        .external()
        .build()
    ; 
}

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

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


2

यदि आप updateRowफ़ंक्शन को संशोधित कर सकते हैं , तो शायद आप इसे दो कार्यों में बदल सकते हैं। यह देखते हुए कि फ़ंक्शन बूलियन पैरामीटर लेता है, मुझे संदेह है कि यह इस तरह दिखता है:

function updateRow(var item, bool externalCall) {
  Database.update(item);

  if (externalCall) {
    Service.call();
  }
}

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

function updateRowAndService(var item) {
  updateRow(item);
  Service.call();
}

function updateRow(var item) {
  Database.update(item);
}

अब, कहीं भी आप इन फ़ंक्शन को कॉल करते हैं, तो आप एक नज़र में बता सकते हैं कि क्या बाहरी सेवा को बुलाया जा रहा है।

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


0

यदि UpdateRow एक नियंत्रित कोडबेस में है, तो मैं रणनीति पैटर्न पर विचार करूंगा:

public delegate void Request(string query);    
public void UpdateRow(Item item, Request request);

जहाँ अनुरोध कुछ प्रकार के DAO (तुच्छ मामले में कॉलबैक) का प्रतिनिधित्व करता है।

सच मामला:

UpdateRow(item, query =>  queryDatabase(query) ); // perform remote call

गलत मामला:

UpdateRow(item, query => readLocalCache(query) ); // skip remote call

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

UpdateRow(item, query => {
  var data = readLocalCache(query);
  if (data == null) {
    data = queryDatabase(query);
  }
  return data;
} );

सामान्य तौर पर, नियंत्रण का ऐसा उलटना आपके डेटा स्टोरेज और मॉडल के बीच कम युग्मन को सुनिश्चित करता है।

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