क्या एकल उत्तरदायित्व सिद्धांत कार्यों के लिए लागू है?


17

रॉबर्ट सी। मार्टिन के अनुसार, एसआरपी में कहा गया है कि:

एक वर्ग को बदलने के लिए एक से अधिक कारण कभी नहीं होने चाहिए ।

हालाँकि, अपनी पुस्तक क्लीन कोड , अध्याय 3: कार्य में, वह कोड के निम्नलिखित ब्लॉक को दिखाता है:

    public Money calculatePay(Employee e) throws InvalidEmployeeType {
        switch (e.type) {
            case COMMISSIONED:
                return calculateCommissionedPay(e);
            case HOURLY:
                return calculateHourlyPay(e);
            case SALARIED:
                return calculateSalariedPay(e);
            default:
                throw new InvalidEmployeeType(e.type);
        }
    }

और फिर कहता है:

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

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


5
यह बहुरूपता के लिए एक पाठ्यपुस्तक के मामले जैसा लगता है।
वचर्जिन

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

जवाबों:


13

सिंगल रिस्पांसिबिलिटी प्रिंसिपल का एक बार याद किया गया विवरण यह है कि "परिवर्तन के कारण" का उपयोग केस-केस एक्टर्स द्वारा किया जाता है (आप यहां पूर्ण विवरण देख सकते हैं )।

इसलिए, आपके उदाहरण में, calculatePayजब भी नए प्रकार के कर्मचारियों की आवश्यकता होती है , तो विधि को बदलना होगा। चूंकि एक प्रकार के कर्मचारी का दूसरे के साथ कुछ भी नहीं हो सकता है, यह सिद्धांत का उल्लंघन होगा यदि आप उन्हें एक साथ रखते हैं, क्योंकि परिवर्तन सिस्टम में विभिन्न उपयोगकर्ता-समूहों (या उपयोग-केस एक्टर्स) को प्रभावित करेगा।

अब, इस बारे में कि क्या सिद्धांत कार्यों पर लागू होता है: भले ही आपके पास केवल एक विधि में उल्लंघन हो, फिर भी आप एक से अधिक कारणों से वर्ग बदल रहे हैं, इसलिए यह अभी भी SRP का उल्लंघन है।


1
मैंने लिंक किए गए यूट्यूब वीडियो को देखने की कोशिश की, लेकिन 10 मिनट के बाद इसमें उपयोग-मामले के अभिनेताओं द्वारा समूहीकरण का कोई उल्लेख नहीं था, मैंने छोड़ दिया। पहले 6 मिनट में सभी लोग बिना किसी स्पष्ट कारण के एन्ट्रापी के बारे में बताते हैं। यदि आपने वीडियो में एक स्थान दिया है जहां वह इस पर चर्चा करना शुरू करता है, तो यह मददगार होगा।
माइकल शॉ

@ मिचेलशॉ 10:40 पर देखने की कोशिश करें। चाचा बॉब का उल्लेख है कि कोड "अलग-अलग लोगों के कारण अलग-अलग कारणों से बदल जाएगा"। मुझे लगता है कि मिशेल हेनरिक हमें बताने की कोशिश कर रहे हैं।
Enrique

पूरा 50 मिनट का यूट्यूब वीडियो देखना समाप्त हो गया, जिसमें से अधिकांश के बारे में यह स्पष्ट नहीं था कि यह क्या स्पष्ट करना चाहिए था। मैंने 16:00 के निशान पर ध्यान दिया कि वह पहले से ही उस विषय से आगे बढ़ गया था, और वह कभी नहीं लौटा। "स्पष्टीकरण" अनिवार्य रूप से इसके लिए उबलता है: एसआरपी में "जिम्मेदारी" का मतलब यह नहीं है कि, इसका अर्थ है "परिवर्तन के विभिन्न कारण", जिसका वास्तव में अर्थ है "विभिन्न लोगों के अनुरोध पर परिवर्तन", जिसका वास्तव में अर्थ है "परिवर्तन" विभिन्न भूमिकाओं का अनुरोध जो लोग निभाते हैं ”। "स्पष्टीकरण" कुछ भी स्पष्ट नहीं करता है, यह एक अस्पष्ट शब्द को दूसरे के साथ बदल देता है।
माइकल शॉ

2
@ मिचेलशॉ पुस्तक के उद्धरण की तरह, यदि आपको विभिन्न कर्मचारी प्रकारों को पेश करने की आवश्यकता है, तो आपको कर्मचारी वर्ग को बदलना होगा। विभिन्न प्रकार के कर्मचारियों के भुगतान के लिए विभिन्न भूमिकाएं जिम्मेदार हो सकती हैं, इसलिए इस मामले में, कर्मचारी वर्ग को एक से अधिक भूमिका के लिए बदलना होगा, इसलिए एसआरपी का उल्लंघन।
मिशेल हेनरिक

1
@MichaelShaw हाँ, आप सही हैं - SRP इस बात पर निर्भर करता है कि संगठन कैसे व्यवस्थित है। यही कारण है कि मैं अपनी सभी टिप्पणियों में "मई" या "हो सकता है" जोड़ता हूं :)। हालांकि, उन मामलों में भी, जबकि कोड एसआरपी का उल्लंघन नहीं कर सकता है, यह निश्चित रूप से ओसीपी का उल्लंघन करता है।
मिशेल हेनरिक

3

पृष्ठ १ On६, अध्याय १२ पर: उद्भव, खंड में न्यूनतम वर्ग और विधियाँ शीर्षक से पुस्तक कुछ हद तक सुधार प्रदान करती है:

हमारी कक्षाओं और विधियों को छोटा बनाने के प्रयास में, हम बहुत से छोटे वर्ग और विधियाँ बना सकते हैं। इसलिए यह नियम बताता है कि हम अपने कार्य और वर्ग को कम रखते हैं

तथा

उच्च वर्ग और पद्धति मायने रखती है कभी-कभी व्यर्थ डोगमेटिज़्म का परिणाम होता है।

जाहिर है, वह एसआरपी का अनुसरण करने के लिए ऊपर की तरह बिल्कुल ठीक निर्दोष छोटे तरीकों को तोड़ने के लिए कुत्ते के शिकार के बारे में बात कर रहा है calculatePay()


3

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

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

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

यदि आप देखते हैं कि क्या calculatePayकरता है, यह स्पष्ट रूप से एक ही काम कर रहा है: प्रकार के आधार पर प्रेषण। चूंकि जावा ने टाइप-आधारित प्रेषण करने के तरीके निर्मित किए हैं, calculatePayअयोग्य और गैर-मुहावरेदार हैं, इसलिए इसे फिर से लिखा जाना चाहिए, लेकिन बताए गए कारणों के लिए नहीं।


-2

आप सही हैं @Enrique। कोई फर्क नहीं पड़ता अगर यह एक फ़ंक्शन या एक कक्षा की विधि है, तो SRP का अर्थ है कि उस कोड ब्लॉक में आप केवल एक ही काम करते हैं।

'कारण परिवर्तन करने के लिए' बयान कभी कभी थोड़ा भ्रामक है, लेकिन अगर आप बदलना calculateSalariedPayया calculateHourlyPayया के enum Employee.typeआप इस विधि का बदलना होगा।

अपने उदाहरण में समारोह:

  • कर्मचारी के प्रकार की जाँच करता है
  • एक अन्य फ़ंक्शन को कॉल करता है जो प्रकार के अनुसार धन की गणना करता है

मेरे विचार में यह सीधे तौर पर SRP उल्लंघन नहीं है, क्योंकि स्विच-केस और कॉल को छोटा नहीं लिखा जा सकता है, यदि आप कर्मचारी के बारे में सोचते हैं और पहले से मौजूद तरीके हैं। वैसे भी यह एक स्पष्ट खुले-बंद सिद्धांत (OCP) का उल्लंघन है क्योंकि आपको कर्मचारी प्रकारों को जोड़ने पर 'केस' के बयानों को जोड़ना चाहिए, इसलिए यह एक बुरा कार्यान्वयन है: इसे फिर से भरें।

हम नहीं जानते कि 'मनी' की गणना कैसे की जानी चाहिए, लेकिन सबसे आसान तरीका Employeeइंटरफ़ेस और getMoneyतरीकों के साथ कुछ ठोस कार्यान्वयन है । उस मामले में पूरा कार्य बेकार है।

यदि इसकी गणना करना अधिक जटिल है, तो कोई विज़िटर-पैटर्न का उपयोग कर सकता है जो 100% एसआरपी भी नहीं है लेकिन यह स्विच के मामले की तुलना में अधिक ओसीपी है।


2
यकीन नहीं है कि आप फ़ंक्शन को 2 चीजें कैसे सूचीबद्ध कर सकते हैं, लेकिन यह कहें कि यह एसआरपी उल्लंघन नहीं है।
जेफ़ो

@ जेफ़ो: यह 2 चीजें नहीं हैं, यह एक बात के 2 भाग हैं: प्रकार के आधार पर उपयुक्त फ़ंक्शन को कॉल करना।
माइकल शॉ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.