2008-09-15 13 views
52

wikipedia article के बारे में Law of Demeter का कहना है:क्या धाराप्रवाह इंटरफेस डेमेटर के कानून का उल्लंघन करते हैं?

कानून को बस "केवल का उपयोग एक डॉट" कहा जा सकता है।

हालांकि एक fluent interface के simple example कुछ ऐसा दिखाई देगा:

इस एक साथ चला जाता है
static void Main(string[] args) 
{ 
    new ZRLabs.Yael.Pipeline("cat.jpg") 
     .Rotate(90) 
     .Watermark("Monkey") 
     .RoundCorners(100, Color.Bisque) 
     .Save("test.png"); 
} 

तो करता है?

उत्तर

71

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

यह भी ध्यान दें कि "कानून" केवल "शास्त्रीय" एपीआई के लिए एक सर्वोत्तम अभ्यास सलाह है। Fluent इंटरफेस एपीआई डिजाइन के लिए एक पूरी तरह से अलग दृष्टिकोण हैं और डेमेटर के कानून के साथ मूल्यांकन नहीं किया जा सकता है।

+11

कोई तर्क दे सकता है कि एक धाराप्रवाह इंटरफ़ेस डेमेटर के कानून का उल्लंघन नहीं करता है क्योंकि आप केवल एक ही ऑब्जेक्ट को डॉट श्रृंखला में एक्सेस कर रहे हैं। – MSN

+0

इस पर ध्यान देने का दूसरा तरीका यह है कि एक धाराप्रवाह इंटरफेस बस क्रमबद्ध संचालन करने का एक वैकल्पिक, कॉम्पैक्ट तरीका है जिससे राज्य उत्परिवर्तन दूर हो जाता है, क्योंकि प्रत्येक मध्यवर्ती चरण के परिणाम निहित होते हैं। –

8

हां, हालांकि आपको स्थिति में कुछ व्यावहारिकता लागू करनी है। मैं हमेशा एक नियम के विरोध में एक दिशानिर्देश के रूप में डेमेटर का कानून लेता हूं। जैसा कि हम में से अधिक ORM जो आम तौर पर एक वस्तु ग्राफ यह हो सकता है के रूप में प्रस्तुत करता है पूरे डोमेन का उपयोग

CurrentCustomer.Orders[0].EmailManufacturer(text); 

:

CurrentCustomer.Orders[0].Manufacturer.Address.Email(text); 

शायद के साथ बदलें:

निश्चित रूप से आप अच्छी तरह से निम्नलिखित से बचना चाहें किसी विशेष वस्तु के लिए स्वीकार्य "दायरा" को परिभाषित करने का विचार बनें। शायद हमें यह सुझाव देने के लिए डेमेटर का कानून लेना चाहिए कि आपको पूरे ग्राफ को पहुंचने योग्य नहीं होना चाहिए।

+3

मुझे लगता है कि एकल जिम्मेदारी सिद्धांत मतलब करने के लिए लिया जा सकता है "पर एक विधि की जरूरत नहीं है अपने ईमेल भेजने के लिए व्यापार वस्तु "। –

23

आवश्यक नहीं है। "केवल एक बिंदु का उपयोग करें" डेमेटर के कानून का एक गलत सारांश है।

Demeter के कानून जब प्रत्येक डॉट एक अलग वस्तु, का परिणाम का प्रतिनिधित्व करता है कई बिंदुओं का उपयोग को हतोत्साहित जैसे:

  • पहले डॉट एक विधि ObjectA से कहा जाता है, प्रकार का ऑब्जेक्ट लौटने है ObjectB
  • अगला डॉट प्रकार का ऑब्जेक्ट लौटने ObjectC
  • अगला डॉट एक संपत्ति केवल ObjectC में
  • अनंत तक
उपलब्ध है, एक विधि केवल ObjectB में उपलब्ध है

हालांकि, कम से कम मेरी राय में, Demeter के कानून का उल्लंघन नहीं है, तो प्रत्येक डॉट की वापसी वस्तु अभी भी मूल फोन करने वाले के रूप में एक ही प्रकार है:

var List<SomeObj> list = new List<SomeObj>(); 
//initialize data here 
return list.FindAll(i => i == someValue).Sort(i1, i2 => i2 > i1).ToArray(); 

उपरोक्त उदाहरण में, दोनों FindAll () और सॉर्ट करें() उसी प्रकार की ऑब्जेक्ट को मूल सूची के रूप में वापस कर दें। डेमेटर के कानून का उल्लंघन नहीं किया जाता है: सूची केवल अपने तत्काल मित्रों से बात की जाती है।

कहा जा रहा है कि सभी धाराप्रवाह इंटरफेस डेमेटर के कानून का उल्लंघन करते हैं, जब तक वे अपने कॉलर के समान प्रकार लौटते हैं।

6

डेमेटर के कानून की भावना यह है कि, किसी ऑब्जेक्ट संदर्भ या कक्षा को देखते हुए, आपको एक वर्ग की संपत्तियों तक पहुंचने से बचना चाहिए जो एक से अधिक उप-संपत्ति या विधि से दूर है क्योंकि इससे दो वर्गों को कसकर जोड़ा जा सकता है, जो हो सकता है अनियंत्रित और रखरखाव की समस्याएं पैदा कर सकते हैं।

Fluent इंटरफेस कानून के एक स्वीकार्य अपवाद के बाद से वे मतलब कम से कम कुछ हद तक कसकर सभी गुण के रूप में मिलकर होने के लिए कर रहे हैं और तरीकों एक मिनी भाषा है कि एक साथ बना रहे हैं कार्यात्मक वाक्य बनाने के लिए के मामले हैं।

1

आपके उदाहरण में कोई समस्या नहीं है। आखिरकार, आप घुमा रहे हैं, वॉटरमार्किंग, आदि ... हमेशा एक ही छवि। मेरा मानना ​​है कि आप हर समय एक पाइपलाइन ऑब्जेक्ट से बात कर रहे हैं, इसलिए जब तक आपका कोड केवल पाइपलाइन की कक्षा पर निर्भर करता है, आप LoD का उल्लंघन नहीं कर रहे हैं।

6

1) यह बिल्कुल इसका उल्लंघन नहीं करता है।

कोड

var a = new ZRLabs.Yael.Pipeline("cat.jpg"); 
a = a.Rotate(90); 
a = a.Watermark("Monkey"); 
a = a.RoundCorners(100, Color.Bisque); 
a = a.Save("test.png"); 

2) के रूप में अच्छा Ol 'फिल Haack कहते हैं के बराबर है: The Law of Demeter Is Not A Dot Counting Exercise

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