2016-03-10 8 views
5

के विकिपीडिया साथ शुरू करते हैं:डेमेटर का कानून क्या है?

अधिक औपचारिक रूप से, कार्यों के लिए Demeter के कानून की आवश्यकता है कि एक विधि एक वस्तु का मीटरहे केवल वस्तुओं में निम्न प्रकार के विधियां प्रारंभ हो सकता है:

  1. हे ही
  2. मीटर के मापदंडों
  3. किसी ऑब्जेक्ट का निर्माण/मी
  4. भीतर instantiated 63,210
  5. हे की प्रत्यक्ष घटक
  6. एक वैश्विक चर, सुलभ वस्तुओं हे द्वारा, मीटर के दायरे में

नियम 1:

public class ClassOne { 

    public void method1() { 
     method2(); 
    } 

    public void method2() { 

    } 
} 

नियम 2:

public class ClassOne { 

    public void method1(ClassTwo classTwo) { 
     classTwo.method2(); 
    } 
} 

class ClassTwo { 

    public void method2() { 

    } 
} 

नियम 3:

public class ClassOne { 

    public void method1() { 
     ClassTwo classTwo = new ClassTwo(); 
     classTwo.method2(); 
    } 
} 

class ClassTwo { 

    public void method2() { 

    } 
} 

नियम 4 (धन्यवाद @juharr):

public class ClassOne { 

    private ClassTwo classTwo; 

    public void method1() { 
     classTwo = new ClassTwo(); 
     classTwo.method2(); 
    } 
} 

class ClassTwo { 

    public void method2() { 

    } 
} 

नियम 5:

? 

किसी को भी मुझे नियम 5 के साथ मदद कर सकते हैं?


और डेमेटर का कानून यह नहीं दर्शाता कि चेनिंग खराब है?

User.getName().getLastName(); 

इससे उच्च युग्मन होता है।


एक समान सिद्धांत "बताओ, मत पूछो" नहीं है?

तो यह सब कुछ है? क्या मैं कुछ गलत हूँ? आप डेमेटर के कानून का पालन कैसे कर सकते हैं?

+0

हां, मूल रूप से "डेमेटर" को यह कहने के लिए पढ़ा जा सकता है: चेनिंग खराब है। अंतिम चीज पर कुछ करने के लिए आपको कुछ पाने के लिए कुछ नहीं मिलता है। – GhostCat

+2

नियम 4 है यदि 'क्लासऑन' के पास 'क्लासटवो' प्रकार का एक निजी क्षेत्र (घटक) है, तो आप उस क्षेत्र पर 'क्लासऑन' में अपनी विधि से विधियों को कॉल कर सकते हैं। – juharr

+0

@juharr धन्यवाद! – Anonymous

उत्तर

3

"पूछो मत पूछो" थोड़ा अलग है।

डेमेटर: अंतिम चीज़ पर कुछ करने के लिए कुछ प्राप्त करने के लिए कुछ प्राप्त न करें।

टीडीए: किसी अन्य ऑब्जेक्ट से "जानकारी" पुनर्प्राप्त न करें, फिर उस पर निर्णय लें। सरल उदाहरण:

if (someList.size() == 0) { bla 

बनाम

if (someList.isEmpty()) { bla 

दोनों ही मामलों आप किसी अन्य वस्तु पर एक विधि बुला रहे हैं में; लेकिन एक महत्वपूर्ण अंतर है: पहला कॉल आपको उस अन्य वस्तु की "आंतरिक" स्थिति का खुलासा करता है; जिस पर आप कुछ निर्णय लेते हैं।जबकि, "टीडीए" में दूसरे संस्करण में सुधार हुआ; आप उस अन्य वस्तु के भीतर "स्थिति मूल्यांकन" छोड़ देते हैं; इस प्रकार किसी भी तरह युग्मन कम करना।

2

सी # या जावा में 5 वां प्रतिनिधित्व करना मुश्किल है, क्योंकि वे तकनीकी रूप से वैश्विक चर का समर्थन नहीं करते हैं। हालांकि, एक डिजाइन पैटर्न में जो सिद्धांत में समान है, आप उदा। एक विन्यास वर्ग है कि बस जैसे (सी #) विश्व स्तर पर सुलभ स्थिर कॉन्फ़िगरेशन मान, शामिल हैं:

internal class MyConfiguration 
{ 
    private static String MyConfigurationValue; // set in constructor 
    MyConfiguration(){ MyConfigurationValue = DoSomethingToLoadValue(); } 
    public static String GetMyConfigurationValue(){ return MyConfigurationValue; } 
} 

इस मामले में (यह मानते हुए डिजाइन पैटर्न अन्य सभी मायनों में स्वीकार्य था), Demeter के कानून इस अनुमति होगी, चूंकि यह वैश्विक रूप से सुलभ है और इस तरह से बनने का इरादा है।

+0

तो "MyConfigurationValue" फ़ील्ड सार्वजनिक नहीं होना चाहिए? – Anonymous

+0

@Robiow इस उदाहरण में नहीं, क्योंकि इससे पता चलता है कि वैश्विक तरीके से कॉन्फ़िगरेशन जानकारी कैसे प्रदान की जाए, लेकिन हम नहीं चाहते हैं कि अन्य वर्ग इसे या तो दुर्घटना या उद्देश्य से बदल सकें। आम तौर पर, जब आप गुणों को पढ़ने और संशोधित करने की अनुमति देते हैं, तो एक क्षेत्र सार्वजनिक बनाना आवश्यक है (उन लोगों के लिए जो "संपत्ति" दृष्टिकोण का पक्ष लेते हैं, मैं यह इंगित करता हूं कि संपत्तियां केवल यह कहने में सक्षम होने के लिए एक चुस्त तरीका है सदस्य चर निजी हैं, भले ही वे काम करते हैं जैसे वे सार्वजनिक हैं, उन तरीकों के माध्यम से जो दृश्यों के पीछे ओवरहेड जोड़ते हैं)। –

1

नियम 5 के लिए एक उदाहरण होगा:

public class ClassOne { 
    public void method1() { 
     classTwo.STATIC_INSTANCE.method2(); 
    } 
} 

class ClassTwo { 
    public static final ClassTwo STATIC_INSTANCE = ...; 

    public void method2() { 
    } 
} 

Enums मूल रूप से इस तरह से काम करते हैं, और यह पहुँच enums करने के लिए ठीक है।


आपका उदाहरण:

user.getName().getLastName(); 

जाहिर है, कानून के विपरीत है क्योंकि वस्तु आप से मिलता है "getName()" सूचीबद्ध किसी भी श्रेणी में आते हैं नहीं होंगे। नोट: इस गलत भले ही आप चेन कॉल का उपयोग नहीं कर रहे हैं:

Name name = user.getName(); 
name.getLastName(); // <- this is still wrong 
वस्तु "नाम" के बाद से

अभी भी सूचीबद्ध किसी भी श्रेणी में नहीं आता।

हालांकि इस तरह की बातें ठीक हैं:

reportBuilder.withMargin(5).withFooter(10) 
    .withBorder(Color.black).build(); 

क्यों इस अनुमति दी है? क्योंकि जब भी निर्माता को अपरिवर्तनीय के रूप में कार्यान्वित किया जाता है, तो आपको हर बार एक ही वस्तु (रिपोर्टबिल्डर) वापस मिलती है, या हो सकता है कि हर बार एक नई वस्तु हो। किसी भी तरह से, यह कानून 2 या 3 में पड़ता है, तो यह ठीक है या तो।


आपका तीसरा सवाल "कैसे पालन करें" है। खैर, यह एक जटिल सवाल है, लेकिन शुरू करने के लिए, इस बारे में सोचें कि कानूनों द्वारा वास्तव में किस तरह के तरीकों को मना किया जाता है!

बस कानूनों को नकारात्मक में डाल दें: हमें उन वस्तुओं पर विधियों को कॉल नहीं करना चाहिए जो पहले से मौजूद हैं (क्योंकि नई वस्तुएं छूट दी गई हैं), और मेरी वस्तु, या मेरी वस्तु के क्षेत्र या मेरे पैरामीटर नहीं हैं। इसलिए अन्य ऑब्जेक्ट्स के क्षेत्र में मौजूद वस्तुओं को छोड़ देता है!

तो मूल रूप से इसका मतलब है कि आपको उन वस्तुओं तक पहुंच प्राप्त करने में सक्षम नहीं होना चाहिए जो आपके क्षेत्र में नहीं, बल्कि प्रत्यक्ष पैरामीटर नहीं हैं। जिसे मैं "नो गेटर्स" के रूप में सारांशित करता हूं!

संबंधित मुद्दे