कोहिज़न (सामंजस्य) एक मीट्रिक है जो दिखाता है कि एक मॉड्यूल या क्लास के अंदर तत्व कितने निकटता से संबंधित हैं। Wikipedia के अनुसार, उच्च सामंजस्य एक अच्छी तरह से डिज़ाइन किए गए मॉड्यूल की विशेषता है, जहाँ सभी विधियाँ और फ़ील्ड एक ही कार्य पर काम करते हैं। कोहिज़न सीधे कोड की रखरखाव क्षमता को प्रभावित करता है और इसे कपलिंग — मॉड्यूल के बीच अंतर्संबंध — के विपरीत रखा जाता है।
मुख्य बातें
कोहिज़न एक मीट्रिक है जो मूल्यांकन करता है कि एक क्लास या मॉड्यूल के अंदर विधियाँ, फ़ील्ड और गुण तार्किक रूप से कितने जुड़े हुए हैं। एक उच्च-सामंजस्य मॉड्यूल एक कार्य करता है और उसमें केवल वही तत्व होते हैं जो उसे पूरा करने के लिए आवश्यक हैं। निम्न-सामंजस्य मॉड्यूल एक साथ कई चीज़ें करने की कोशिश करता है — इसकी विधियाँ अर्थ में कमज़ोर रूप से संबंधित होती हैं।
ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग के संदर्भ में, सामंजस्य एकल उत्तरदायित्व सिद्धांत (S) से निकटता से जुड़ा है। यदि एक क्लास की एक स्पष्ट जिम्मेदारी है, तो उसका सामंजस्य आम तौर पर उच्च होता है। यदि एक क्लास एक साथ UI, व्यावसायिक तर्क और नेटवर्किंग संभालती है — तो सामंजस्य कम है, और ऐसी क्लास को संकीर्ण जिम्मेदारियों वाली कई अलग-अलग क्लासों में विभाजित किया जाना चाहिए।
सामंजस्य को समझना डेवलपर्स को रीफैक्टरिंग निर्णय लेने में मदद करता है। जब आप किसी क्लास में कोई ऐसी विधि देखते हैं जो क्लास के किसी भी फ़ील्ड का उपयोग नहीं करती, तो यह निम्न सामंजस्य का संकेत है। ऐसी विधि या तो क्लास में गलत जगह पर है, या क्लास खराब डिज़ाइन की गई है। उच्च सामंजस्य के लिए प्रयास करना कोड के हर स्तर पर आर्किटेक्चर को बेहतर बनाने का एक सतत प्रयास है।
सॉफ़्टवेयर इंजीनियरिंग में, सामंजस्य के सात स्तरों को प्रतिष्ठित किया जाता है, जो सबसे खराब से सर्वश्रेष्ठ तक क्रमबद्ध हैं। इस पैमाने को समझना आपको एक मॉड्यूल की गुणवत्ता का निष्पक्ष मूल्यांकन करने और रीफैक्टरिंग की दिशा निर्धारित करने की अनुमति देता है। स्तर जितना ऊँचा होगा, कोड उतना ही अधिक रखरखाव योग्य और समझने योग्य होगा।
आकस्मिक — सबसे खराब स्तर, जहाँ एक मॉड्यूल में तत्व बिना किसी तार्किक संबंध के यादृच्छिक रूप से समूहित होते हैं। उदाहरण: एक Utilities क्लास जिसमें दिनांक स्वरूपण, ईमेल भेजने और छूट की गणना करने की विधियाँ हैं। ऐसी क्लास को उसकी सभी विधियों को पढ़े बिना नहीं समझा जा सकता, और एक विधि को बदलने से दूसरी टूट सकती हैं सिर्फ इसलिए कि वे एक साथ हैं।
तार्किक — तत्व तार्किक रूप से संबंधित लेकिन मौलिक रूप से भिन्न कार्य करते हैं। parseJSON, parseXML और parseCSV विधियों वाली एक क्लास “पार्सिंग” के विषय से तार्किक रूप से जुड़ी है, लेकिन प्रत्येक विधि मौलिक रूप से भिन्न कार्य करती है। समस्या: जब एक नया प्रारूप (YAML) जोड़ा जाता है, तो क्लास बढ़ती है और उसका इंटरफ़ेस फूल जाता है।
लौकिक — तत्व निष्पादन समय के अनुसार समूहित होते हैं। एक AppInitializer क्लास जो डेटाबेस सेट करती है, कॉन्फ़िगरेशन लोड करती है और एनालिटिक्स को आरंभ करती है — यह सब ऐप स्टार्टअप पर होता है, लेकिन कार्य स्वयं असंबंधित हैं। बेहतर है कि उन्हें जिम्मेदारी के प्रत्येक क्षेत्र के लिए अलग-अलग Initializers में विभाजित किया जाए।
प्रक्रियात्मक — तब होता है जब तत्व निष्पादन के अनुक्रम से एकजुट होते हैं। एक “ऑर्डर प्रोसेसिंग” मॉड्यूल में validateCart, processPayment और sendConfirmation विधियाँ होती हैं — प्रत्येक विधि पिछले एक के बाद सख्ती से बुलाई जाती है। यह आकस्मिक या तार्किक सामंजस्य से बेहतर है, लेकिन फिर भी आदर्श नहीं है: प्रत्येक चरण को एक अलग मॉड्यूल में निकाला जा सकता है।
संचारात्मक — तत्व एक ही डेटा के साथ काम करते हैं। getUser, updateUser और deleteUser विधियों वाली एक UserService क्लास सामान्य User इकाई से एकजुट है। यह प्रक्रियात्मक सामंजस्य से काफी बेहतर है: क्लास का एक स्पष्ट डोमेन है। मोबाइल प्रोजेक्ट्स में अधिकांश Repository क्लासों में संचारात्मक सामंजस्य होता है।
कार्यात्मक — उच्चतम स्तर, जहाँ मॉड्यूल का प्रत्येक तत्व एक ही कार्य करने में भाग लेता है। एक PasswordValidator क्लास जिसमें एक ही validate विधि है जो लंबाई, वर्णों की उपस्थिति और पासवर्ड जटिलता की जाँच करती है — कार्यात्मक सामंजस्य का उदाहरण है। यदि ऐसी क्लास बदलती है, तो केवल इसलिए कि पासवर्ड सत्यापन नियम बदल गए हैं।
कार्यात्मक सामंजस्य प्राप्त करना आर्किटेक्चरल रीफैक्टरिंग का प्राथमिक लक्ष्य है। प्रत्येक क्लास में बदलाव का exactly एक कारण होना चाहिए। मोबाइल डेवलपमेंट में, कार्यात्मक सामंजस्य अलग-अलग Use Cases, कस्टम Views, फ़ॉर्मेटर और वैलिडेटर निकालकर प्राप्त किया जाता है। ऐसी प्रत्येक क्लास जिम्मेदारी के स्पष्ट क्षेत्र के साथ एक पूर्ण बिल्डिंग ब्लॉक है।
कोहिज़न और कपलिंग एक ही गुणवत्ता के दो पहलू हैं। एक मॉड्यूल के अंदर सामंजस्य जितना अधिक होगा, मॉड्यूल के बीच कपलिंग उतनी ही कम होगी। एक अच्छी तरह से डिज़ाइन की गई प्रणाली एक साथ उच्च आंतरिक सामंजस्य और ढीली बाहरी कपलिंग के लिए प्रयास करती है। इस सिद्धांत को 1970 के दशक से सॉफ़्टवेयर इंजीनियरिंग में मौलिक माना जाता है।
सामंजस्य-कपलिंग संबंध को एक संतुलन के रूप में सोचा जा सकता है। यदि कोई डेवलपर एक क्लास में कई कार्यों को मिलाकर सामंजस्य का त्याग करता है, तो पड़ोसी मॉड्यूल को अधिक निर्भरताएँ मिलती हैं — उन्हें विभिन्न उद्देश्यों के लिए इस ओवरलोडेड क्लास तक पहुँचना पड़ता है, जो कपलिंग को बढ़ाता है। इसके विपरीत, छोटी, उच्च-सामंजस्य क्लासों में विभाजन मॉड्यूल के बीच इंटरैक्शन बिंदुओं की संख्या को कम करता है।
व्यवहार में, इसका अर्थ है: जब आप कार्यात्मक सामंजस्य के साथ एक नई क्लास निकालते हैं, तो आप एक साथ अन्य मॉड्यूल को इसके कार्यान्वयन के विवरण जानने की आवश्यकता से मुक्त करते हैं। उदाहरण के लिए, EncryptionManager को कार्यात्मक सामंजस्य के साथ एक अलग क्लास में निकालने से अन्य मॉड्यूल को एन्क्रिप्शन एल्गोरिथम के विवरण को समझे बिना एक सरल encrypt/decrypt इंटरफ़ेस मिलता है।
// निम्न सामंजस्य — क्लास एक ही बार में सब कुछ करती है
class UserManager {
fun fetchAndSaveUser(id: String) { }
fun parseUserJson(json: String): User { }
fun displayUserName(user: User): String { }
fun validateEmail(email: String): Boolean { }
}
// उच्च सामंजस्य — प्रत्येक क्लास एक कार्य हल करती है
class UserRepository {
fun fetchUser(id: String): User { }
}
class UserJsonParser {
fun parse(json: String): User { }
}
class UserNameFormatter {
fun format(user: User): String { }
}
class EmailValidator {
fun isValid(email: String): Boolean { }
}
उदाहरण अंतर दिखाता है: UserManager में तार्किक सामंजस्य है — सभी विधियाँ उपयोगकर्ताओं के बारे में हैं, लेकिन प्रत्येक मौलिक रूप से भिन्न कार्य करती है। रीफैक्टरिंग के बाद, प्रत्येक क्लास में कार्यात्मक सामंजस्य होता है, और कपलिंग कम हो जाती है क्योंकि अन्य मॉड्यूल केवल उस क्लास पर निर्भर होते हैं जिसकी उन्हें आवश्यकता है, न कि पूरे UserManager पर।
LCOM (विधियों के सामंजस्य की कमी) क्लास सामंजस्य को मापने के लिए सबसे प्रसिद्ध मीट्रिक है। LCOM गणना करता है कि विधियों के कितने जोड़े सामान्य फ़ील्ड साझा नहीं करते हैं। मान 0 का अर्थ आदर्श सामंजस्य है (सभी विधियाँ समान फ़ील्ड के साथ काम करती हैं), जबकि उच्च मान निम्न सामंजस्य को इंगित करता है। LCOM4 (एक बेहतर संस्करण) अन्य विधियों के माध्यम से संक्रामक कनेक्शनों को ध्यान में रखता है।
Android डेवलपमेंट में, TooManyFunctions नियम के साथ Detekt के माध्यम से सामंजस्य मीट्रिक प्राप्त किए जा सकते हैं। दर्जनों विधियों वाली क्लासें जो फ़ील्ड के विभिन्न समूहों का उपयोग करती हैं, संभवतः निम्न सामंजस्य रखती हैं। iOS में, SwiftLint के पास file_length और function_body_length नियम हैं — अप्रत्यक्ष संकेतक: लंबी फ़ाइलें और विधियाँ अक्सर निम्न सामंजस्य का संकेत देती हैं।
एक मैनुअल मूल्यांकन विधि: प्रश्न पूछें “क्या यह क्लास एक कारण से या कई कारणों से बदलेगी?” यदि आप एक से अधिक स्वतंत्र कारण बता सकते हैं — क्लास में निम्न सामंजस्य है। दूसरा परीक्षण: “क्या इस क्लास को दो स्वतंत्र क्लासों में विभाजित किया जा सकता है?” यदि हाँ — तो करें। कोड समीक्षाओं में नियमित रूप से सामंजस्य की जाँच करना God क्लासों को रोकता है और तकनीकी ऋण को कम करता है।
पहला कदम — एकल उत्तरदायित्व सिद्धांत लागू करना। प्रत्येक क्लास की एक स्पष्ट जिम्मेदारी होनी चाहिए। यदि किसी क्लास में कोई विधि है जो उसके मुख्य कार्य से संबंधित नहीं है, तो उसे एक अलग क्लास में निकालें। IDE में Extract Class या Extract Delegate तकनीक इस प्रक्रिया को स्वचालित करती है। निष्कर्षण के बाद, जाँचें कि क्या मूल क्लास अधिक केंद्रित हो गई है।
दूसरा कदम — इंटरफ़ेस को सरल बनाने के लिए Facade पैटर्न का उपयोग करना। यदि कोई क्लास 20 विधियाँ प्रदान करती है लेकिन क्लाइंट केवल 3-4 का उपयोग करते हैं, तो क्लास में निम्न सामंजस्य हो सकता है — यह बहुत अधिक विविध कार्यक्षमता प्रदान करती है। विधियों को विषय के अनुसार समूहित करें, प्रत्येक समूह के लिए अलग-अलग क्लास निकालें, और मूल क्लास को या तो फ़ेसेड बनाएँ या हटा दें।
तीसरा कदम — फ़ील्ड समूहों पर ध्यान देना। यदि किसी क्लास में ऐसे फ़ील्ड हैं जो केवल विधियों के एक उपसमूह द्वारा उपयोग किए जाते हैं — यह निम्न सामंजस्य का संकेतक है। क्लास को फ़ील्ड समूहों द्वारा विभाजित करें। उदाहरण के लिए, यदि किसी क्लास में userRepository, networkClient और analyticsTracker फ़ील्ड हैं, लेकिन विधियों का पहला समूह केवल userRepository का उपयोग करता है जबकि दूसरा networkClient का — ये दो अलग-अलग क्लास हैं।
चौथा कदम — मनमानी static विधियों वाली “utility” क्लास बनाने से बचना। Utils या Helpers क्लास में बैठी प्रत्येक static विधि एक विशेष क्लास में निष्कर्षण के लिए उम्मीदवार है। FormatUtils.dateToString को DateFormatter में ले जाना बेहतर है, और ValidationUtils.isValidEmail को EmailValidator में। यह प्रत्येक क्लास के सामंजस्य को बढ़ाता है और कोड को स्व-दस्तावेज़ीकरण बनाता है।
अक्सर पूछे जाने वाले प्रश्न
लगभग हमेशा। कार्यात्मक सामंजस्य कोड को स्पष्ट और पूर्वानुमानित बनाता है। हालाँकि, इसे चरम पर ले जाने से अत्यधिक विखंडन हो सकता है: प्रत्येक ऑपरेशन के लिए एक अलग क्लास बनाना, जिससे आर्किटेक्चर अत्यधिक जटिल हो जाता है। संतुलन प्रति सुविधा कुछ क्लास हैं, प्रत्येक कार्यात्मक सामंजस्य के साथ।
सामंजस्य एक एकल मॉड्यूल या क्लास के भीतर आंतरिक स्थिरता का मीट्रिक है। मॉड्यूलरिटी एक आर्किटेक्चरल सिद्धांत है जहाँ एक एप्लिकेशन को भौतिक मॉड्यूल में विभाजित किया जाता है। उच्च सामंजस्य व्यक्तिगत क्लास और संपूर्ण मॉड्यूल दोनों को डिज़ाइन करते समय एक लक्ष्य है।
Detekt Android के लिए और Xcode Analyzer iOS के लिए संदिग्ध रूप से कई विधियों या फ़ील्ड वाली क्लास को हाइलाइट करते हैं। IntelliJ IDEA और AppCode में निर्भरता विज़ुअलाइज़ेशन है — आप कनेक्शन ग्राफ़ देख सकते हैं और निम्न सामंजस्य वाली क्लास का पता लगा सकते हैं। SonarQube स्वचालित रूप से LCOM मीट्रिक की गणना करता है।
हाँ। connect, disconnect और isConnected विधियों वाले एक इंटरफ़ेस में उच्च सामंजस्य है — सभी विधियाँ कनेक्शन प्रबंधन से संबंधित हैं। connect, parseData और renderUI विधियों वाले इंटरफ़ेस में निम्न सामंजस्य है। इंटरफ़ेस पृथक्करण सिद्धांत (SOLID) के लिए उच्च सामंजस्य के साथ संकीर्ण रूप से केंद्रित इंटरफ़ेस बनाने की आवश्यकता होती है।
तीन प्रश्न पूछें: क्या क्लास के उद्देश्य को एक वाक्य में वर्णित किया जा सकता है? क्या सभी विधियाँ इस उद्देश्य का समर्थन करती हैं? क्या क्लास में ऐसे फ़ील्ड हैं जिनका उपयोग कुछ विधियों द्वारा नहीं किया जाता? यदि किसी प्रश्न का उत्तर नहीं है — सामंजस्य कम है, और क्लास को विभाजित किया जाना चाहिए।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें