पिछले कुछ वर्षों में, हम धीरे-धीरे उत्तरोत्तर बेहतर लिखित कोड पर स्विच कर रहे हैं, एक समय में कुछ बच्चे कदम रखते हैं। हम अंत में कुछ करने के लिए स्विच बनाना शुरू कर रहे हैं जो कम से कम 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 के साथ असंगत हैं, और कुछ ऑपरेशन की पेचीदगियों को संभालने के लिए लॉजिक तरीके बनाए।