लेगसी Swift कोड का रिफैक्टरिंग: उन्नत तकनीकें

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

परिचय: लेगसी Swift कोड का रिफैक्टरिंग एक कला क्यों है

\n

Swift में पुराने कोड के साथ काम करना iOS/macOS डेवलपर के सबसे कठिन और जिम्मेदारी भरे कार्यों में से एक है। लेगसी प्रोजेक्ट्स में अक्सर «दिव्य ऑब्जेक्ट» (God objects), UIKit पर अत्यधिक निर्भरता, परीक्षणों की कमी और अव्यवस्थित आर्किटेक्चर होता है। उन्नत रिफैक्टरिंग केवल वेरिएबल का नाम बदलना नहीं है, बल्कि 100% कार्यक्षमता बनाए रखते हुए कोड बेस का एक व्यवस्थित परिवर्तन है। इस लेख में, हम उन तकनीकों पर चर्चा करेंगे जो अराजकता को एक सहनीय आर्किटेक्चर में बदलने में मदद करेंगी।

\n\n

1. मॉड्यूलरीकरण: मोनोलिथ को घटकों में विभाजित करना

\n

सभ्य कोड की ओर पहला कदम स्वतंत्र मॉड्यूल को अलग करना है। एक विशाल टार्गेट के बजाय, हम अलग-अलग फ्रेमवर्क या Swift Package Manager मॉड्यूल बनाते हैं।

\n\n

मॉड्यूल की सीमाएँ निर्धारित करना

\n

हम «High Cohesion, Low Coupling» सिद्धांत का उपयोग करते हैं। उदाहरण: नेटवर्क अनुरोध परत, व्यावसायिक तर्क परत और UI परत को अलग करना।

\n\n
// पहले: सब कुछ एक ViewController फ़ाइल में\nclass LegacyViewController: UIViewController {\n    func fetchData() {\n        // URLSession कोड यहाँ\n    }\n    func parseData() {\n        // JSON पार्सिंग यहाँ\n    }\n}\n\n// बाद में: Network मॉड्यूल\npublic class NetworkService {\n    public func fetchData(completion: @escaping (Result<Data, Error>) -> Void) {\n        // स्वच्छ नेटवर्क परत\n    }\n}\n
\n\n

फ़ेसेड के माध्यम से माइग्रेशन

\n

मौजूदा कोड को न तोड़ें: एक फ़ेसेड बनाएं जो नए मॉड्यूल को कॉल सौंपता है। धीरे-धीरे पुराने कॉल को बदलें।

\n\n
class LegacyNetworkFacade {\n    private let newService = NetworkService()\n    \n    @objc func oldFetchMethod() {\n        newService.fetchData { result in\n            // पुराने API के अनुकूलन\n        }\n    }\n}\n
\n\n

2. ग्लोबल सिंगलटन के बजाय डिपेंडेंसी इंजेक्शन (DI)

\n

लेगसी कोड अक्सर सिंगलटन से ग्रस्त होता है: UserManager.shared, APIClient.shared। यह परीक्षण को असंभव बना देता है। DI पर स्विच करें।

\n\n

इनिशियलाइज़र के माध्यम से मैन्युअल इंजेक्शन

\n
// समस्या\nclass OldViewModel {\n    let api = APIClient.shared\n    let user = UserManager.shared\n}\n\n// समाधान\nprotocol APIClientProtocol { /* ... */ }\nprotocol UserManagerProtocol { /* ... */ }\n\nclass NewViewModel {\n    private let api: APIClientProtocol\n    private let userManager: UserManagerProtocol\n    \n    init(api: APIClientProtocol, userManager: UserManagerProtocol) {\n        self.api = api\n        self.userManager = userManager\n    }\n}\n
\n\n

DI-कंटेनर का एकीकरण (Swinject/Resolver)

\n

बड़े प्रोजेक्ट्स के लिए लाइब्रेरी का उपयोग करें। Resolver के साथ उदाहरण:

\n
import Resolver\n\nextension Resolver: ResolverRegistering {\n    public static func registerAllServices() {\n        register { NetworkService() as NetworkServiceProtocol }\n        register { UserDefaultsStorage() as StorageProtocol }\n    }\n}\n\nclass RefactoredViewModel {\n    @Injected private var network: NetworkServiceProtocol\n    @Injected private var storage: StorageProtocol\n}\n
\n\n

3. परीक्षण: परीक्षणों के संरक्षण में रिफैक्टरिंग

\n

परीक्षणों के बिना, रिफैक्टरिंग रूसी रूलेट खेलने जैसा है। पुराने कोड के लिए «टेस्ट फ्रेमवर्क» (characterization tests) बनाएं।

\n\n

लेगसी कोड के लिए Characterization tests

\n

वर्तमान व्यवहार को परीक्षणों के रूप में रिकॉर्ड करें, भले ही वह आदर्श न हो।

\n
class LegacyCalculatorTests: XCTestCase {\n    func testLegacyMultiply() {\n        // वर्तमान व्यवहार को कैप्चर करें\n        let result = LegacyCalculator().multiply(2, 3)\n        XCTAssertEqual(result, 6) // भले ही तर्क अजीब हो\n    }\n}\n
\n\n

गोल्डन मास्टर के साथ समानांतर रिफैक्टरिंग

\n

पुराने और नए कार्यान्वयन के आउटपुट की तुलना करें। पहचान की जाँच के लिए XCTAssertEqual का उपयोग करें।

\n\n
func testRefactoredMatchesL                

ब्लॉग

पुस्तक अनुशंसाएँ