यह मुझे नहीं लगता इस परिवर्तन Law of Demeter से कोई लेना देना नहीं है। कानून, अनिवार्य रूप से, अन्य ऑब्जेक्ट्स की पूरी श्रृंखला के माध्यम से विधियों को कॉल करके अपने ऑब्जेक्ट ग्राफ़ की संरचना को आपके कोड में एन्कोड करने के बारे में है। उदाहरण के लिए, मान लीजिए, एक कार बीमा आवेदन में, कि ग्राहक के पास पॉलिसी है, और पॉलिसी में वाहन हैं, और वाहनों के पास ड्राइवर हैं, और ड्राइवरों की जन्मतिथि होती है और इस प्रकार उम्र होती है।
public boolean hasUnderageDrivers(Customer customer) {
for (Vehicle vehicle : customer.getPolicy().getVehicles()) {
for (Driver driver : vehicle.getDrivers()) {
if (driver.getAge() < 18) {
return true;
}
}
}
return false;
}
इसका कारण यह है इस कोड को अब internals के ज्ञान यह पता करने की जरूरत नहीं है कि है Demeter के कानून का उल्लंघन होगा: आप निम्नलिखित कोड कल्पना कर सकता। यह जानता है कि बीमा पॉलिसी को पूरी तरह से बीमा पॉलिसी को सौंपने के बजाय वाहनों को सौंपा गया है। यदि, भविष्य में, बीमा कंपनी ने फैसला किया कि ड्राइवर विशेष रूप से विशेष वाहनों को सौंपे जाने के बजाय नीति पर होंगे, तो इस कोड को बदलना होगा।
समस्या यह अपने पैरामीटर, getPolicy()
की एक विधि कॉल, और फिर एक और, getVehicles()
, और फिर एक और, getDrivers()
, और फिर एक और, getAge()
है। Demeter के कानून का कहना है कि एक वर्ग की एक विधि पर ही तरीकों बुलाना चाहिए:
- ही
- इसका क्षेत्रों
- इसके मापदंडों
- वस्तुओं यह
(पिछले एक बनाता है यूनिट परीक्षण के लिए एक समस्या हो सकती है, जहां आप सीधे स्थानीय रूप से बनाए गए बजाय कारखानों द्वारा इंजेक्शन या बनाई गई वस्तुएं ले सकते हैं, लेकिन यह डेमेटर के कानून से प्रासंगिक नहीं है।)
हम Policy
वस्तु में पारित कर सकते हैं hasUnderageDrivers()
साथ समस्या को ठीक करने और हम कैसे जानता है कि चाहे नीति नाबालिग ड्राइवर हैं निर्धारित करने के लिए Policy
पर एक विधि हो सकता है:
public boolean hasUnderageDrivers(Policy policy) {
return policy.hasUnderageDrivers();
}
एक स्तर कॉलिंग नीचे, customer.getPolicy().hasUnderageDrivers()
, शायद — है डेमेटर का कानून अंगूठे का नियम है, न कि कठिन और तेज़ नियम। आपको शायद उन चीजों के बारे में ज्यादा चिंता करने की ज़रूरत नहीं है जिन्हें बदलने की संभावना नहीं है; Driver
शायद हमेशा जन्म तिथि और getAge()
विधि जारी रखने जा रहा है।
लेकिन आपके मामले में लौटने पर, क्या होगा यदि हम इन सभी गेटर्स को सार्वजनिक क्षेत्रों के साथ बदल दें? यह डेमेटर के कानून में बिल्कुल मदद नहीं करता है। पहले उदाहरण में आप अभी भी वही समस्या कर सकते हैं। पर विचार करें:
public boolean hasUnderageDrivers(Customer customer) {
for (Vehicle vehicle : customer.policy.vehicles) {
for (Driver driver : vehicle.drivers) {
if (driver.age < 18) {
return true;
}
}
}
return false;
}
(। मैं भी, driver.age
करने के लिए driver.getAge()
परिवर्तित कर दिया है, हालांकि कि शायद नहीं बल्कि एक साधारण क्षेत्र से जन्म तिथि के आधार एक गणना होगा)
सूचना है कि embedding के साथ सटीक एक ही समस्या ऑब्जेक्ट ग्राफ़ को एकसाथ कैसे रखा जाता है (एक ग्राहक की नीति होती है जिसमें वाहन होते हैं) मौजूद होते हैं जब हम गेटर्स के बजाय सार्वजनिक फ़ील्ड के साथ कोड लिखते हैं। समस्याएं एक साथ रखी जाती हैं कि टुकड़ों को कैसे रखा जाता है, न कि गेटर्स को बुलाया जा रहा है या नहीं।
संयोग से, सार्वजनिक क्षेत्रों में गेटर्स (अंतिम?) से अधिक पसंद करने का सामान्य कारण यह है कि आपको बाद में उनके पीछे कुछ तर्क डालना पड़ सकता है। जन्म तिथि और आज की तारीख के आधार पर गणना के साथ एक आयु को प्रतिस्थापित किया जाता है, या एक सेटटर को कुछ सत्यापन होना चाहिए (उदाहरण के लिए, यदि आप null
पास करते हैं तो फेंकता है)। मैंने पहले उस संदर्भ में डेमेटर के कानून को नहीं सुना है।
ऐसा लगता है जैसे आपके साथियों के पास पर्याप्त काम नहीं है। – Sneftel
हाँ, यह समस्या है .. हमारे पास काम करने का एक टन है, और यह एक बड़ी रिफैक्टर है और 100 फाइलों की तरह छूता है। मैं वापस पुश करने के लिए जा रहा हूँ, और मैं सिर्फ यकीन है कि मैं सिर्फ से अधिक है बनाना चाहते "यह समय की बर्बादी है" (जो है, हालांकि यह के दम पर पर्याप्त होना चाहिए) – alexD
सौभाग्य से आप ग्रूवी जहां 'x.getStuff उपयोग नहीं कर रहे() 'और' x.stuff' हैं अविवेच्य (और जहां क्षेत्र 'stuff' भी कॉल समय में मौजूद हो सकता है नहीं ...) –