SOLID पर स्विच करने के बाद बड़े पैमाने पर बढ़ी हुई कक्षाओं का प्रबंधन और आयोजन?


49

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

स्विच बनाने के लिए शुरू करने से पहले, हमारी वास्तुकला को निम्न की तरह बहुत व्यवस्थित किया गया था (दी गई, एक या दो आदेशों के साथ अधिक फाइलें):

Solution
- Business
-- AccountLogic
-- DocumentLogic
-- UsersLogic
- Entities (Database entities)
- Models (Domain Models)
- Repositories
-- AccountRepo
-- DocumentRepo
-- UserRepo
- ViewModels
-- AccountViewModel
-- DocumentViewModel
-- UserViewModel
- UI

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

मैं पूरी ईमानदारी से हमारे कोडबेस को बेहतर बनाने के लिए किए जाने वाले हर प्रयास का समर्थन करता हूं, लेकिन इस तरह के बड़े पैमाने पर बदलावों पर बाकी टीम से कुछ पुश-बैक मिलना बहुत आम है। वर्तमान में सबसे बड़े चिपके हुए बिंदु हैं:

  • यूनिट टेस्ट
  • कक्षा की गणना
  • सहकर्मी समीक्षा जटिलता

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

क्लास काउंट शायद सबसे बड़ी बाधा है। जो टास्क 5-10 फाइल लेते थे वो अब 70-100 ले सकते हैं! जबकि इनमें से प्रत्येक फाइलें एक अलग उद्देश्य से काम करती हैं, फाइलों की भारी मात्रा भारी हो सकती है। टीम की प्रतिक्रिया ज्यादातर कराह रही है और सिर खुजला रही है। पहले एक कार्य में एक या दो रिपॉजिटरी, एक मॉडल या दो, एक तर्क परत और एक नियंत्रक विधि की आवश्यकता हो सकती है।

अब, एक साधारण फ़ाइल सेविंग एप्लिकेशन बनाने के लिए आपके पास यह जांचने के लिए एक वर्ग है कि क्या फ़ाइल पहले से मौजूद है, मेटाडेटा लिखने के लिए एक वर्ग, एक वर्ग को दूर करने के लिए DateTime.Nowताकि आप यूनिट परीक्षण के लिए समय इंजेक्ट कर सकें, तर्क युक्त हर फाइल के लिए इंटरफेस, फाइलें वहाँ प्रत्येक वर्ग के लिए इकाई परीक्षण शामिल करने के लिए, और अपने DI कंटेनर में सब कुछ जोड़ने के लिए एक या अधिक फाइलें।

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


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

दस्तावेज़ को नेटवर्क ड्राइव में सहेजने के लिए, मुझे कुछ विशिष्ट वर्गों की आवश्यकता थी:

- IBasePathProvider 
-- string GetBasePath() // returns the network path to store files
-- string GetPatientFolderName() // gets the name of the folder where patient files are stored
- BasePathProvider // provides an implementation of IBasePathProvider
- BasePathProviderTests // ensures we're getting what we expect

- IUniqueFilenameProvider
-- string GetFilename(string path, string fileType);
- UniqueFilenameProvider // performs some filesystem lookups to get a unique filename
- UniqueFilenameProviderTests

- INewGuidProvider // allows me to inject guids to simulate collisions during unit tests
-- Guid NewGuid()
- NewGuidProvider 
- NewGuidProviderTests

- IFileExtensionCombiner // requests may come in a variety of ways, need to ensure extensions are properly appended.
- FileExtensionCombiner
- FileExtensionCombinerTests

- IPatientFileWriter
-- Task SaveFileAsync(string path, byte[] file, string fileType)
-- Task SaveFileAsync(FilePushRequest request) 
- PatientFileWriter
- PatientFileWriterTests

इसलिए कुल 15 कक्षाएं (POCO और मचान को छोड़कर) एक काफी सरल बचत करने के लिए हैं। जब मैंने कुछ सिस्टमों में संस्थाओं का प्रतिनिधित्व करने के लिए POCOs बनाने के लिए इस संख्या को गुब्बारा बनाया, तो कुछ थर्ड पार्टी सिस्टम के साथ संवाद करने के लिए कुछ रिपोज बनाया, जो हमारे अन्य ORM के साथ असंगत हैं, और कुछ ऑपरेशन की पेचीदगियों को संभालने के लिए लॉजिक तरीके बनाए।


52
"5-10 फाइलें लेने के लिए जो कार्य अब 70-100 ले सकते हैं!" नरक में कैसे? यह किसी भी तरह से सामान्य नहीं है। आप किस तरह के बदलाव कर रहे हैं जिसमें कई फाइलों को बदलने की आवश्यकता है ??
व्यंग्यात्मक

43
तथ्य यह है कि आपको प्रति कार्य अधिक फ़ाइलों को बदलना होगा (काफी अधिक!) इसका मतलब है कि आप SOLID गलत कर रहे हैं। पूरा बिंदु आपके कोड को समय के साथ व्यवस्थित करना है, जो कि बदले हुए पैटर्न को दर्शाता है, जिससे परिवर्तन सरल हो जाते हैं। SOLID में प्रत्येक सिद्धांत इसके पीछे कुछ तर्क के साथ आता है (जब और क्यों इसे लागू किया जाना चाहिए); ऐसा लगता है कि आपने इन स्थितियों में आँख बंद करके इस स्थिति में खुद को पा लिया है। इकाई परीक्षण (टीडीडी) के साथ एक ही बात; यदि आप इसे डिज़ाइन / आर्किटेक्चर के बारे में अच्छी समझ के बिना कर रहे हैं, तो आप अपने आप को एक छेद में खोदने जा रहे हैं।
फिलिप मिलोवानोविक

60
आपने स्पष्ट रूप से काम करने में मदद करने के लिए एक व्यावहारिक उपकरण के बजाय SOLID को एक धर्म के रूप में अपनाया है। अगर SOLID में कुछ अधिक काम कर रहा है या चीजों को अधिक कठिन बना रहा है, तो ऐसा न करें।
whatsisname

25
@ यूफ़ोरिक: समस्या दोनों तरीकों से हो सकती है। मुझे संदेह है कि आप इस संभावना पर प्रतिक्रिया दे रहे हैं कि 70-100 कक्षाएं ओवरकिल हैं। लेकिन यह असंभव नहीं है कि यह सिर्फ एक बड़े पैमाने पर परियोजना हो, जो 5-10 फ़ाइलों में crammed थी (मैंने पहले 20KLOC फ़ाइलों में काम किया है ...) और 70-100 वास्तव में फाइलों की सही मात्रा है।
फ्लाटर

18
विचार का एक विकार है जिसे मैं "ऑब्जेक्ट सुख रोग" कहता हूं, जो यह विश्वास है कि ओओ तकनीक एक बड़े कोडबेस में काम करने की लागत को कम करने के लिए कई संभावित तकनीकों में से केवल एक के बजाय खुद में एक अंत है। आपके पास एक विशेष रूप से उन्नत रूप है, "ठोस खुशी रोग"। ठोस लक्ष्य नहीं है। कोडबेस को बनाए रखने की लागत को कम करना लक्ष्य है। उस संदर्भ में अपने प्रस्तावों का मूल्यांकन करें, न कि यह कि क्या सिद्धांत SOLID में हैं। (यह कि आपके प्रस्ताव भी वास्तव में सिद्धांत नहीं हैं, SOLID भी विचार करने के लिए एक अच्छा बिंदु है।)
एरिक लिपर्ट

जवाबों:


104

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

मुझे लगता है कि आपने एक ही जिम्मेदारी के विचार को गलत समझा है। एक कक्षा की एकल जिम्मेदारी "फ़ाइल को सहेजना" हो सकती है। ऐसा करने के लिए, फिर यह उस जिम्मेदारी को एक ऐसी विधि में तोड़ सकता है जो यह जांचती है कि क्या कोई फ़ाइल मौजूद है, एक विधि जो मेटाडेटा आदि लिखती है। प्रत्येक उन विधियों में तब एक ही जिम्मेदारी होती है, जो कक्षा की समग्र जिम्मेदारी का हिस्सा है।

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

आपको "तर्क युक्त हर फ़ाइल के लिए इंटरफेस" की आवश्यकता नहीं है, आपको उन वर्गों के लिए इंटरफेस की आवश्यकता है जिनके दुष्प्रभाव हैं, जैसे कि वे कक्षाएं जो फाइलों या डेटाबेसों को पढ़ती / लिखती हैं; और फिर भी, वे केवल उस कार्यक्षमता के सार्वजनिक भागों के लिए आवश्यक हैं। इसलिए उदाहरण के लिए AccountRepo, आपको किसी इंटरफेस की आवश्यकता नहीं हो सकती है, आपको केवल वास्तविक डेटाबेस एक्सेस के लिए एक इंटरफ़ेस की आवश्यकता हो सकती है जो उस रेपो में इंजेक्ट किया जाता है।

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

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

तो अगर आपके कोड के हिस्सों को वास्तव में अन्य भागों को प्रभावित किए बिना पूरे के रूप में परीक्षण किया जा सकता है, तो ऐसा करें।

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


27
मैं जोड़ना चाहूंगा कि एक समान सिरदर्द तब उत्पन्न होता है जब लोग "विधियों को केवल एक ही काम करना चाहिए" के बार-बार मंत्र का पालन करने की कोशिश करते हैं और एक लाइन विधियों के टन के साथ समाप्त होते हैं क्योंकि यह तकनीकी रूप से एक विधि में बनाया जा सकता है ।
लॉग

8
पुन "हमेशा व्यावहारिक हो सकता है और याद सब कुछ एक समझौता है" अंकल बॉब चेलों इस के लिए नहीं जाना जाता है (चाहे मूल उद्देश्य):।
पीटर मोर्टेंसन

13
पहले भाग को योग करने के लिए, आपके पास आमतौर पर एक कॉफी इंटर्न होता है, न कि प्लग-इन-पर्कोलेटर, फ्लिप-स्विच, चेक-इफ-शुगर-रीफिलिंग, ओपन-फ्रिज, गेट-आउट-मिल्क का पूरा सूट -आउट-स्पून, गेट-डाउन-कप, डालना-कॉफी, ऐड-शुगर, एड-मिल्क, हलचल-कप और डिलीवर-कप इंटर्न। ; पी
जस्टिन टाइम 2

12
ओपी की समस्या का मूल कारण उन कार्यों के अंतर को गलत समझना है जो एक ही कार्य करना चाहिए , और एक वर्ग जिसके पास एक ही जिम्मेदारी
एलेफ़ेज़ेरो

6
"नियम बुद्धिमान पुरुषों के मार्गदर्शन और मूर्खों की आज्ञाकारिता के लिए हैं।" - डगलस बैडर
कैलनस

29

जो टास्क 5-10 फाइल लेते थे वो अब 70-100 ले सकते हैं!

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

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

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

उन्हीं कारणों से एक साथ चीजों को इकट्ठा करें । उन चीजों को अलग करें जो अलग-अलग कारणों से बदलती हैं।

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

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

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


1
मुझे लगता है मैं सिर्फ यह पता लगाने की कोशिश कर रहा हूं कि लाइन कहां है। हाल ही के एक कार्य में, मुझे काफी सरल ऑपरेशन करना पड़ा, लेकिन यह बहुत मौजूदा मचान या कार्यक्षमता के बिना एक कोडबेस में था। जैसे, मुझे जो कुछ भी करने की ज़रूरत थी वह बहुत सरल था, लेकिन सभी बहुत ही अद्वितीय थे और साझा कक्षाओं में फिट नहीं थे। मेरे मामले में, मुझे एक दस्तावेज़ को एक नेटवर्क ड्राइव में सहेजने की आवश्यकता थी, और इसे दो अलग-अलग डेटाबेस तालिकाओं में लॉग इन करें। प्रत्येक चरण के आसपास के नियम काफी विशेष थे। यहां तक ​​कि फ़ाइल नाम पीढ़ी (एक साधारण गाइड) के पास परीक्षण को अधिक सुविधाजनक बनाने के लिए कुछ कक्षाएं थीं।
JD डेविस

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

सहमत, मैं इसे जोड़ता हूं। विकिपीडिया को उद्धृत करने के लिए, "मार्टिन एक जिम्मेदारी को बदलने के कारण के रूप में परिभाषित करता है, और निष्कर्ष निकालता है कि एक वर्ग या मॉड्यूल में एक होना चाहिए, और केवल एक, कारण बदला जाना (यानी फिर से लिखा गया)।" और "उन्होंने हाल ही में कहा" यह सिद्धांत लोगों के बारे में है। "" वास्तव में, मेरा मानना ​​है कि इसका मतलब है कि एसआरपी में "जिम्मेदारी" हितधारकों को संदर्भित करती है, कार्यक्षमता को नहीं। एक वर्ग को केवल एक हितधारक (जिस व्यक्ति को आपके कार्यक्रम को बदलने की आवश्यकता होती है) द्वारा आवश्यक परिवर्तनों के लिए जिम्मेदार होना चाहिए, ताकि आप बदलाव की मांग करने वाले विभिन्न हितधारकों के जवाब में FEW चीजों के रूप में बदल सकें।
Corrodias

12

जो टास्क 5-10 फाइल लेते थे वो अब 70-100 ले सकते हैं!

यह एक झूठ है। कार्यों ने कभी केवल 5-10 फाइलें नहीं लीं।

आप 10 से कम फ़ाइलों वाले किसी भी कार्य को हल नहीं कर रहे हैं। क्यों? क्योंकि आप C # का उपयोग कर रहे हैं। C # एक उच्च स्तरीय भाषा है। आप केवल हैलो दुनिया बनाने के लिए 10 से अधिक फ़ाइलों का उपयोग कर रहे हैं।

ओह, यकीन है कि आप उन्हें नोटिस नहीं करते क्योंकि आपने उन्हें नहीं लिखा था। इसलिए आप उनमें नहीं दिखते। आप उन पर भरोसा करते हैं।

समस्या फ़ाइलों की संख्या नहीं है। यह है कि अब आपके पास इतना चल रहा है कि आपको भरोसा नहीं है।

इसलिए यह पता लगाने के लिए कि उन परीक्षणों को इस बिंदु पर कैसे काम किया जाए कि एक बार जब वे पास हो जाएं तो इन फाइलों पर भरोसा करें जिस तरह से आप .NET में फाइलों पर भरोसा करते हैं। ऐसा करना इकाई परीक्षण का बिंदु है। फ़ाइलों की संख्या के बारे में कोई परवाह नहीं करता है। वे उन चीजों की संख्या की परवाह करते हैं जिन पर वे भरोसा नहीं कर सकते।

छोटे से मध्यम आकार के अनुप्रयोगों के लिए, SOLID एक सुपर आसान बिक्री है। हर कोई लाभ और स्थिरता को आसानी से देखता है। हालाँकि, वे सिर्फ बड़े पैमाने पर अनुप्रयोगों के लिए SOLID के लिए एक अच्छा मूल्य प्रस्ताव नहीं देख रहे हैं।

परिवर्तन बहुत बड़े पैमाने पर अनुप्रयोगों पर कठिन है कोई भी मैटर आप क्या करते हैं। सबसे अच्छा ज्ञान यहाँ लागू करने के लिए अंकल बॉब से नहीं आता है। यह माइकल फेदर की अपनी पुस्तक वर्किंग इफेक्टिवली विथ लेगेसी कोड में आता है।

फिर से लिखना शुरू न करें। पुराना कोड कठिन ज्ञान का प्रतिनिधित्व करता है। इसे टॉस करना क्योंकि इसमें समस्याएं हैं और नए और बेहतर प्रतिमान में व्यक्त नहीं किया गया है एक्स केवल समस्याओं का एक नया सेट और कोई कठिन जीता ज्ञान नहीं है।

इसके बजाय परीक्षण योग्य बनाने के तरीके खोजें अपने पुराने अप्रतिष्ठित कोड (फेज़र्स स्पीक में विरासत कोड)। इसमें रूपक कोड एक शर्ट की तरह है। बड़े हिस्से प्राकृतिक सीमों में शामिल हो जाते हैं जो कोड को अलग करने के लिए पूर्ववत किया जा सकता है जिस तरह से आप सीम को हटा देंगे। ऐसा करने के लिए आपको परीक्षण "आस्तीन" संलग्न करने की अनुमति दें जो आपको बाकी कोड को अलग करने दें। अब जब आप परीक्षण आस्तीन बनाते हैं तो आप आस्तीन में आत्मविश्वास रखते हैं क्योंकि आपने एक काम करने वाले शर्ट के साथ ऐसा किया था। (अरे, यह रूपक चोट करने लगा है)।

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

इसका किसी से क्या लेना देना है:

SOLID पर स्विच करने के बाद बड़े पैमाने पर बढ़ी हुई कक्षाओं का प्रबंधन और आयोजन?

अमूर्त।

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

मुझे एक अच्छा नाम, पठनीय परीक्षण (उदाहरण) दें जो दिखाते हैं कि इंटरफ़ेस का उपयोग कैसे करें, और इसे व्यवस्थित करें ताकि मैं चीजों को पा सकूं और मुझे परवाह नहीं है अगर हम 10, 100, या 1000 फ़ाइलों का उपयोग करते हैं।

आप मुझे अच्छे वर्णनात्मक नामों के साथ चीजों को खोजने में मदद करें। अच्छे नामों के साथ चीजों को अच्छे नामों के साथ रखें।

यदि आप यह सब ठीक करते हैं, तो आप उन फाइलों को अमूर्त कर देंगे, जहाँ किसी कार्य को पूरा करने के लिए आपके पास केवल 3 से 5 अन्य फाइलें हैं। 70-100 फाइलें अभी भी हैं। लेकिन वे 3 से 5 के पीछे छिप रहे हैं। यह केवल तभी काम करता है जब आप उस अधिकार को करने के लिए 3 से 5 पर भरोसा करते हैं।

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

@ डेलियोथ बढ़ते दर्द के बारे में एक अच्छी बात करता है । जब आप डिश वॉशर के ऊपर अलमारी में होने वाले व्यंजनों के लिए अभ्यस्त हो जाते हैं, तो उन्हें नाश्ते के बार के ऊपर कुछ उपयोग करने की आदत होती है। कुछ चीजों को कठिन बनाता है। कुछ चीजों को आसान बनाता है। लेकिन यह सभी प्रकार के बुरे सपने का कारण बनता है अगर लोग सहमत नहीं हैं कि व्यंजन कहां जाते हैं। एक बड़े कोड आधार में समस्या यह है कि आप केवल एक समय में कुछ व्यंजनों को स्थानांतरित कर सकते हैं। तो अब आपके पास दो स्थानों पर व्यंजन हैं। यह भ्रमित करने वाला है। यह विश्वास करना मुश्किल है कि व्यंजन वे हैं जहां वे होने वाले हैं। यदि आप इस अतीत को प्राप्त करना चाहते हैं, हालांकि केवल एक ही चीज बर्तन को हिलाती रहती है।

इस समस्या के साथ आप वास्तव में यह जानना चाहेंगे कि क्या यह सब बकवास से गुजरने से पहले नाश्ते के बार में व्यंजन हैं। अच्छी तरह से सभी के लिए मैं सिफारिश कर सकते हैं कि डेरा डाले हुए है।

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

लोगों को खेलने के लिए एक सुरक्षित स्थान देने से उन्हें नए विचारों को अपनाने में मदद मिलेगी और उन्हें विश्वास दिलाया जाएगा कि व्यंजन वास्तव में उनके नए घर में काम कर सकते हैं।


3
यह ध्यान देने योग्य हो सकता है कि प्रश्न के कुछ दर्द की संभावना सिर्फ बढ़ती दर्द के रूप में है - जबकि, हाँ, उन्हें इस एक चीज़ के लिए 15 फाइलें बनाने की आवश्यकता हो सकती है ... अब उन्हें कभी भी एक GUIDProvider, या एक BasePathitrovider लिखना नहीं पड़ता है , या एक ExtensionProvider, आदि। यह एक ही तरह की बाधा है जो आपको तब मिलती है जब आप एक नया ग्रीनफ़ील्ड प्रोजेक्ट शुरू करते हैं - सहायक विशेषताओं के गुच्छा जो लिखने के लिए ज्यादातर तुच्छ, बेवकूफ होते हैं, और फिर भी लिखने की आवश्यकता होती है। उन्हें बनाने के लिए बेकार है, लेकिन एक बार जब वे वहाँ हो तो आपको उनके बारे में सोचने की आवश्यकता नहीं होनी चाहिए .... कभी।
16:10 पर

@ डेलियोथ मैं अविश्वसनीय रूप से यह मानना ​​चाहता हूं कि यह मामला है। पहले, अगर हमें कार्यक्षमता के कुछ सबसेट की आवश्यकता होती है (हम कहते हैं कि हमें बस AppSettings में रखे गए URL की आवश्यकता थी), हमारे पास बस एक विशाल वर्ग था जिसे चारों ओर से पारित किया गया था और उपयोग किया गया था। नए दृष्टिकोण के साथ, AppSettingsकेवल url या फ़ाइल पथ प्राप्त करने के लिए संपूर्णता से गुज़रने का कोई कारण नहीं है।
जेडी डेविस

1
फिर से लिखना शुरू न करें। पुराना कोड कठिन ज्ञान का प्रतिनिधित्व करता है। इसे टॉस करना क्योंकि इसमें समस्याएं हैं और नए और बेहतर प्रतिमान में व्यक्त नहीं किया गया है एक्स केवल समस्याओं का एक नया सेट और कोई कठिन जीता ज्ञान नहीं है। इस। पूर्ण रूप से।
Flot2011

10

ऐसा लगता है जैसे आपका कोड बहुत अच्छी तरह से डिकोड नहीं किया गया है और / या आपके कार्य का आकार बहुत बड़ा है।

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

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

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


2
५-१० से -०-१०० तक की फाइलें काल्पनिक से थोड़ी अधिक है। मेरा अंतिम कार्य हमारे नए माइक्रोसर्विसेज में से कुछ में कार्यक्षमता बनाना था। नई सेवा को एक अनुरोध प्राप्त करना था, और एक दस्तावेज को बचाना था। ऐसा करने के लिए, मुझे 2 अलग-अलग डेटाबेस में उपयोगकर्ता संस्थाओं का प्रतिनिधित्व करने के लिए कक्षाओं की आवश्यकता है और प्रत्येक के लिए रिपॉज करें। मुझे लिखने के लिए आवश्यक अन्य तालिकाओं का प्रतिनिधित्व करने का प्रस्ताव। फ़ाइल-डेटा जाँच और नाम-पीढ़ी को संभालने के लिए समर्पित कक्षाएं। और सूची खत्म ही नहीं होती। उल्लेख नहीं करने के लिए, प्रत्येक वर्ग जिसमें तर्क निहित था, एक इंटरफ़ेस द्वारा प्रस्तुत किया गया था ताकि इकाई परीक्षणों के लिए इसका मजाक उड़ाया जा सके।
जेडी डेविस

1
जहां तक ​​हमारे पुराने कोडबेस हैं, वे सभी कसकर युग्मित और अविश्वसनीय रूप से अखंड हैं। SOLID दृष्टिकोण के साथ, वर्गों के बीच एकमात्र युग्मन POCOs के मामले में रहा है, बाकी सब कुछ DI और इंटरफेस के माध्यम से पारित किया गया है।
जेडी डेविस

3
@JDDavis - ठहरिए, एक माइक्रोसेवक कई डेटाबेस के साथ सीधे काम क्यों कर रहा है?
तेलेस्टीन

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

4

मैं यहाँ पहले से ही बताई गई कुछ चीजों पर विस्तार करना चाहूँगा, लेकिन जहाँ वस्तु सीमाएँ खींची जाती हैं, उनके दृष्टिकोण से अधिक। यदि आप डोमेन-प्रेरित डिज़ाइन के लिए कुछ का अनुसरण कर रहे हैं, तो आपकी वस्तुएँ संभवतः आपके व्यवसाय के पहलुओं का प्रतिनिधित्व करने वाली हैं। Customerऔर Order, उदाहरण के लिए, वस्तुएं होंगी। अब, यदि मुझे उस वर्ग के नामों के आधार पर एक अनुमान लगाना था जो आपके शुरुआती बिंदु के रूप में था, तो आपकी AccountLogicकक्षा में कोड था जो किसी भी खाते के लिए चलेगा । OO में, हालांकि, प्रत्येक वर्ग का संदर्भ और पहचान है। आपको एक Accountवस्तु नहीं मिलनी चाहिए और फिर उसे एक AccountLogicकक्षा में उत्तीर्ण करना चाहिए और उस कक्षा को Accountवस्तु में परिवर्तन करना चाहिए । वह है जिसे एनीमिक मॉडल कहा जाता है, और बहुत अच्छी तरह से OO का प्रतिनिधित्व नहीं करता है। इसके बजाय, आपकेAccountकक्षा में व्यवहार होना चाहिए, जैसे कि Account.Close()या Account.UpdateEmail(), और उन व्यवहारों से खाते का केवल उदाहरण प्रभावित होगा।

अब, इन व्यवहारों को कैसे संभाला जा सकता है (और बहुत से मामलों में) अमूर्त (यानी, इंटरफेस) द्वारा प्रतिनिधित्व की जाने वाली निर्भरता के लिए ऑफ-लोड किया जाना चाहिए। Account.UpdateEmail, उदाहरण के लिए, एक डेटाबेस, या एक फ़ाइल को अपडेट करना चाहते हैं, या एक सेवा बस, आदि के लिए एक संदेश भेज सकते हैं और भविष्य में बदल सकते हैं। इसलिए, आपकी Accountकक्षा पर निर्भरता हो सकती है, उदाहरण के लिए, एक IEmailUpdate, जो किसी AccountRepositoryवस्तु द्वारा लागू किए गए कई इंटरफेस में से एक हो सकता है । आप ऑब्जेक्ट के IAccountRepositoryलिए संपूर्ण इंटरफ़ेस पास नहीं करना चाहेंगे Accountक्योंकि यह संभवतः बहुत अधिक होगा, जैसे कि खोज और अन्य (किसी भी) खाते ढूंढना, जिसे आप नहीं चाहते कि Accountऑब्जेक्ट तक पहुंच हो, लेकिन भले ही AccountRepositoryदोनों को लागू कर सकें IAccountRepositoryऔर IEmailUpdateइंटरफेस,Accountऑब्जेक्ट को केवल उन छोटे भागों तक पहुंच प्राप्त होगी जिनकी उसे आवश्यकता है। यह आपको इंटरफ़ेस अलगाव सिद्धांत को बनाए रखने में मदद करता है ।

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

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


2

इसलिए कुल 15 कक्षाएं (POCO और मचान को छोड़कर) एक काफी सरल बचत करने के लिए हैं।

वह पागल है .... लेकिन इन कक्षाओं में कुछ ऐसा लगता है जैसे मैं खुद लिखूंगा। तो आइए उन पर एक नजर डालते हैं। आइए अब के लिए इंटरफेस और परीक्षणों की अनदेखी करें।

  • BasePathProvider- IMHO फाइलों के साथ काम करने वाले किसी भी गैर-तुच्छ प्रोजेक्ट को इसकी आवश्यकता है। तो मुझे लगता है, वहाँ पहले से ही ऐसी बात है और आप इसका उपयोग कर सकते हैं।
  • UniqueFilenameProvider - यकीन है, आप पहले से ही है, है ना?
  • NewGuidProvider - एक ही मामला है, जब तक आप सिर्फ GUID का उपयोग करने के लिए घूर रहे हैं।
  • FileExtensionCombiner - वही मामला।
  • PatientFileWriter - मुझे लगता है, यह वर्तमान कार्य के लिए मुख्य वर्ग है।

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


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

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

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


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

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

@JDDavis और सब कुछ आपके उपकरणों की गुणवत्ता पर निर्भर करता है। उदाहरण: ऐसे लोग हैं जो दावा कर रहे हैं कि DI उद्यमी है और जटिल है, जबकि मैं दावा कर रहा हूं कि यह ज्यादातर मुफ्त है+++नियमों को तोड़ने के बारे में: चार कक्षाएं हैं, मुझे उन जगहों की आवश्यकता है, जहां मैं केवल एक बड़ी रिफ्लेक्टरिंग के बाद कोड को अधिक बदसूरत बना सकता हूं (कम से कम मेरी आंखों के लिए), इसलिए मैंने उन्हें सिंगलटन (एक बेहतर किसान) बनाने का फैसला किया एक बेहतर तरीका मिल सकता है, लेकिन मैं इसके साथ खुश हूं, इन सिंगलेटों की संख्या उम्र के बाद भी नहीं बदलती है)।
मआर्टिनस

यह जवाब बहुत कुछ व्यक्त करता है कि मैं क्या सोच रहा था जब ओपी ने सवाल का उदाहरण जोड़ा। @JDDavis मुझे जोड़ने दें कि आप सरल मामलों के लिए कार्यात्मक टूल का उपयोग करके कुछ बॉयलरप्लेट कोड / कक्षाएं बचा सकते हैं। एक जीयूआई प्रदाता, उदाहरण के लिए - इसके लिए एक नए इंटरफ़ेस को एक नए वर्ग में घुसने के बजाय, बस इसके लिए उपयोग क्यों नहीं Func<Guid>किया जाता है, और ()=>Guid.NewGuid()निर्माता की तरह एक अनाम विधि को इंजेक्ट करें ? और इस .Net फ्रेमवर्क फ़ंक्शन का परीक्षण करने की कोई आवश्यकता नहीं है, यह कुछ ऐसा है जिसे Microsoft ने आपके लिए किया है। कुल मिलाकर, यह आपको 4 वर्गों को बचाएगा।
डॉक्टर ब्राउन

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

2

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

यहाँ मुझे संदेह है कि यह रेल बंद हो रही है:

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

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

यदि आपकी टीम इकाई परीक्षण नहीं लिख रही है, तो दो संबंधित चीजें हो रही हैं:

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

उदाहरण के लिए, जब रिफ्लेक्टर की जरूरत होती है तो क्या होता है? यदि उन्हें सौ छोटी कक्षाएं मिल गई हैं, लेकिन कोई बदलाव नहीं है, तो उन्हें यह बताने के लिए कि उनके परिवर्तन काम करेंगे या नहीं, उन अतिरिक्त कक्षाओं और इंटरफेस को एक बोझ की तरह लगता है, एक सुधार नहीं।

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

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

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

इसके शीर्ष पर, एक बार जब हम इसे लटका लेते हैं, तो यूनिट परीक्षण लिखने से कोड तेजी से विकसित होता है, धीमा नहीं। हम पुराने कोड या डिबगिंग को फिर से शुरू करने में कम समय बिताते हैं जो उन समस्याओं का पता लगाने के लिए है जो एक घास-फूस की सुई की तरह हैं।

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

स्विच बनाने के बाद से, डेवलपर्स की सबसे बड़ी शिकायतों में से एक यह है कि वे सहकर्मी की समीक्षा करने और खड़े नहीं हो सकते हैं दर्जनों और दर्जनों फाइलें जहां पहले प्रत्येक कार्य को केवल डेवलपर को 5-10 फाइलों को छूने की आवश्यकता थी।

पीयर रिव्यू बहुत आसान है जब सभी यूनिट टेस्ट पास कर लेते हैं और उस रिव्यू का एक बड़ा हिस्सा सिर्फ यह सुनिश्चित कर रहा है कि टेस्ट सार्थक हैं।

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