सिर्फ इसलिए कि एक प्रणाली जटिल है इसका मतलब यह नहीं है कि आपको इसे जटिल बनाना होगा । यदि आपके पास एक वर्ग है जिसमें बहुत अधिक निर्भरता (या सहयोगी) हैं जैसे:
public class MyAwesomeClass {
public class MyAwesomeClass(IDependency1 _d1, IDependency2 _d2, ... , IDependency20 _d20) {
// Assign it all
}
}
... तो यह रास्ता बहुत जटिल हो गया और आप वास्तव में एसआरपी का पालन नहीं कर रहे हैं, क्या आप? मैं शर्त लगा सकता हूं कि अगर आपने लिखा है कि MyAwesomeClass
एक सीआरसी कार्ड पर क्या होता है तो यह एक इंडेक्स कार्ड पर फिट नहीं होगा या आपको वास्तव में छोटे गैरकानूनी पत्रों में लिखना होगा।
यहाँ आपके पास यह है कि आपके लोगों ने इसके बजाय केवल इंटरफ़ेस अलगाव सिद्धांत का पालन किया है और इसे एक चरम पर ले जाया जा सकता है लेकिन यह एक पूरी कहानी है। आप यह तर्क दे सकते हैं कि निर्भरताएँ डोमेन ऑब्जेक्ट्स (जो होती हैं) हालांकि एक क्लास होती हैं जो एक ही समय में 20 डोमेन ऑब्जेक्ट्स को हैंडल करती हैं और इसे बहुत दूर तक फैला रही हैं।
टीडीडी आपको एक अच्छा संकेतक प्रदान करेगा कि एक वर्ग कितना करता है। कुंद डालना; अगर एक परीक्षण विधि में सेटअप कोड होता है जो लिखने के लिए हमेशा के लिए लेता है (भले ही आप परीक्षणों को फिर से तैयार करते हैं) तो आपके पास MyAwesomeClass
शायद बहुत अधिक चीजें हैं।
तो कैसे आप इस पहेली को हल करते हैं? आप अन्य वर्गों के लिए जिम्मेदारियों को आगे बढ़ाते हैं। कुछ ऐसे कदम हैं जिन्हें आप एक वर्ग पर उठा सकते हैं जिसमें यह समस्या है:
- उन सभी कार्यों (या जिम्मेदारियों) को पहचानें जो आपकी कक्षा निर्भरता के साथ करती है।
- कार्यों को बारीकी से संबंधित निर्भरता के अनुसार समूहित करें।
- Redelegate! यानी पहचाने गए कार्यों में से प्रत्येक को नए या (अधिक महत्वपूर्ण रूप से) अन्य वर्गों के लिए रिफ्लेक्टर करें।
जिम्मेदारियों का निर्वाह करने पर एक सार उदाहरण
चलो C
एक वर्ग कई निर्भरता है कि हो सकता है D1
, D2
, D3
, D4
है कि आपको कम उपयोग करने के लिए refactor करने के लिए की जरूरत है। जब हम पहचानते हैं कि C
निर्भरता पर कॉल करने वाले कौन से तरीके हैं, तो हम इसकी एक सरल सूची बना सकते हैं:
D1
- performA(D2)
,performB()
D2
- performD(D1)
D3
- performE()
D4
- performF(D3)
सूची को देखते हुए हम यह देख सकते हैं D1
और D2
एक दूसरे से संबंधित हैं क्योंकि कक्षा को उन्हें किसी भी तरह एक साथ की आवश्यकता है। हम यह भी देख सकते हैं कि D4
जरूरत है D3
। इसलिए हमारे पास दो समूह हैं:
Group 1
- D1
<->D2
Group 2
- D4
->D3
समूह एक संकेतक हैं कि कक्षा में अब दो जिम्मेदारियां हैं।
Group 1
- कॉलिंग दो ऑब्जेक्ट्स को संभालने के लिए एक जो एक दूसरे की आवश्यकता होती है। हो सकता है कि आप अपनी कक्षा C
को दोनों निर्भरता से निपटने की आवश्यकता को समाप्त करने दें और उनमें से एक को कॉल करने के बजाय छोड़ दें। इस समूहीकरण में, यह स्पष्ट है कि D1
इसका संदर्भ हो सकता है D2
।
Group 2
- दूसरी जिम्मेदारी के लिए दूसरे को बुलाने के लिए एक वस्तु की जरूरत होती है। अपनी कक्षा के बजाय D4
संभाल नहीं सकते D3
? तब हम शायद समाप्त कर सकते हैं D3
वर्ग से C
अनुमति देकर D4
बजाय कॉल करते हैं।
मेरे जवाब को पत्थर में सेट मत करो क्योंकि उदाहरण बहुत सार है और बहुत सारी धारणाएं बनाता है। मुझे पूरा यकीन है कि इसे रीफैक्टर करने के और भी तरीके हैं, लेकिन कम से कम कदम आपको वर्गों को विभाजित करने के बजाय जिम्मेदारियों को स्थानांतरित करने के लिए किसी तरह की प्रक्रिया प्राप्त करने में मदद कर सकते हैं।
संपादित करें:
टिप्पणियों के बीच @ ईमद करीम कहते हैं:
"अगर आपकी कक्षा में कंस्ट्रक्टर में 20 पैरामीटर हैं, तो यह आपकी टीम की तरह आवाज़ नहीं करता है, यह जानता है कि एसआरपी क्या है। यदि आपके पास एक वर्ग है जो केवल एक चीज करता है, तो इसके 20 निर्भरताएं कैसे हैं?" - मुझे लगता है कि यदि आप एक ग्राहक वर्ग है, निर्माणकर्ता में 20 पैरामीटर होना कोई अजीब बात नहीं है।
यह सच है कि DAO ऑब्जेक्ट में बहुत सारे पैरामीटर होते हैं, जिन्हें आपको अपने कंस्ट्रक्टर में सेट करना होता है, और पैरामीटर आमतौर पर स्ट्रिंग जैसे सरल प्रकार होते हैं। हालाँकि Customer
, एक वर्ग के उदाहरण में , आप अभी भी चीजों को सरल बनाने के लिए अन्य वर्गों के अंदर गुण कर सकते हैं। जैसे कि Address
सड़कों के साथ एक Zipcode
वर्ग और एक वर्ग जिसमें ज़िपकोड होता है और व्यावसायिक तर्क जैसे डेटा सत्यापन के रूप में अच्छी तरह से काम करेगा:
public class Address {
private String street1;
//...
private Zipcode zipcode;
// easy to extend
public bool isValid() {
return zipcode.isValid();
}
}
public class Zipcode {
private string zipcode;
public bool isValid() {
// return regex match that zipcode contains numbers
}
}
इस बात की चर्चा आगे ब्लॉग पोस्ट "कभी नहीं, कभी नहीं, कभी नहीं स्ट्रिंग में जावा (या कम से कम अक्सर)" का उपयोग करें । निर्माणकर्ताओं या स्थिर तरीकों का उपयोग करने के विकल्प के रूप में उप वस्तुओं को बनाने में आसान बनाने के लिए आप एक द्रव बिल्डर पैटर्न का उपयोग कर सकते हैं ।