लेगेसी Swift कोड का रिफैक्टरिंग: A से Z तक
\nलेगेसी कोड के साथ काम करना iOS/macOS डेवलपर के जीवन का एक अपरिहार्य हिस्सा है। अक्सर यह कोड Swift के शुरुआती संस्करणों या यहाँ तक कि Objective-C में लिखा गया होता है, जिसमें टेस्ट नहीं होते, "मैजिक नंबर्स" और विशाल UIViewController होते हैं। इस लेख में, हम ऐसे कोड के रिफैक्टरिंग की चरण-दर-चरण रणनीति पर चर्चा करेंगे, इसे एक आधुनिक, रखरखाव योग्य और परीक्षण योग्य प्रोजेक्ट में बदल देंगे।
1. तैयारी और सुरक्षा: कोड को छूने से पहले
\nरिफैक्टरिंग का सबसे महत्वपूर्ण नियम: जो काम कर रहा है उसे मत तोड़ो। टेस्ट के बिना, कोई भी बदलाव अज्ञात में छलांग लगाने जैसा है।
\n- \n
- कैरेक्टराइज़ेशन टेस्ट से घेरना: ऐसे टेस्ट लिखें जो वर्तमान व्यवहार को रिकॉर्ड करें। भले ही कोड गलत लगे, पहले उसके काम करने का तरीका दस्तावेज़ित करें। \n
- वर्जन कंट्रोल सिस्टम: वर्तमान स्थिति के साथ एक कमिट करें। फीचर ब्रांच का उपयोग करें। \n
- उपकरण: Xcode जिसमें
Edit > Refactor(Rename, Extract Method) हो, साथ ही एक समान शैली बनाए रखने के लिए लिंटर्स (SwiftLint) हों। \n
// पुराने मेथड के लिए व्यवहार को "फ्रीज़" करने का उदाहरण\nclass LegacyCalculator {\n func calculateTotal(items: [Int]) -> Int {\n // पुराना, अपठनीय लॉजिक\n var result = 0\n for i in items {\n result += i * 2\n }\n return result + 10\n }\n}\n\n// व्यवहार को रिकॉर्ड करने वाला टेस्ट\nfunc testCalculateTotal() {\n let sut = LegacyCalculator()\n let result = sut.calculateTotal(items: [1, 2, 3])\n XCTAssertEqual(result, 22) // (1+2+3)*2 + 10 = 22\n}\n\n\n2. "पंचिंग बैग" रणनीति: ग्लोबल वेरिएबल्स और सिंगलटन
\nलेगेसी कोड अपने ग्लोबल स्टेट्स और सिंगलटन के लिए कुख्यात है। यह कोड को कसकर जोड़ता है और अप्रत्याशित बनाता है।
\nसमस्या:
\nclass NetworkManager {\n static let shared = NetworkManager()\n var baseURL: String = "http://old.api.com"\n func fetchData() { ... }\n}\n\nसमाधान: डिपेंडेंसी इंजेक्शन। एक प्रोटोकॉल बनाएं और इनिशियलाइज़र के माध्यम से डिपेंडेंसी पास करें।
\nprotocol NetworkService {\n func fetchData()\n}\n\nclass ModernViewModel {\n private let network: NetworkService\n \n init(network: NetworkService) {\n self.network = network\n }\n \n func load() {\n network.fetchData()\n }\n}\n\nयह दृष्टिकोण टेस्ट में सेवाओं को आसानी से बदलने की अनुमति देता है और कोड को मॉड्यूलर बनाता है।
\n\n3. "मोटे कंट्रोलर" (Massive View Controller) से लड़ाई
\niOS लेगेसी की क्लासिक समस्या: UIViewController जो नेटवर्क रिक्वेस्ट से लेकर UI फ़ॉर्मेटिंग तक सब कुछ संभालता है। रिफैक्टरिंग जिम्मेदारी के पृथक्करण (SRP) के माध्यम से होती है।
चरण 1: बिज़नेस लॉजिक को एक अलग मॉडल (ViewModel) में निकालें।
\n// कंट्रोलर में था\nfunc buttonTapped() {\n let data = fetchData()\n let total = data.reduce(0, +)\n label.text = "योग: \\(total)"\n}\n\n// अब: ViewModel\nclass MyViewModel {\n func calculateTotal(data: [Int]) -> String {\n let total = data.reduce(0, +)\n return "योग: \\(total)"\n }\n}\n\n\nचरण 2: UI सेटअप को अलग मेथड या फैक्ट्री में निकालें।
\n- \n
- जटिल पदानुक्रमों के लिए एक
ViewBuilderक्लास बनाएं। \n - पुराने
dataSourceके बजायUICollectionViewDiffableDataSourceका उपयोग करें। \n
4. आधुनिकीकरण: Objective-C से Swift और नए API तक
\nअक्सर लेगेसी कोड में Objective-C और Swift का मिश्रण होता है। रिफैक्टरिंग करते समय पुरानी संरचनाओं को अपडेट करना महत्वपूर्ण है:
\n\n- \n
NSErrorकोthrowsसे बदलना: आधुनिक Swift त्रुटि प्रबंधन के लिए अपवादों का उपयोग करता है। \n !(फोर्स अनरैप) को छोड़ना: सुरक्षित अनरैपिंग के लिएguard letयाif letका उपयोग करें। \n