2009-02-25 15 views
27

मैं हाल ही में how to create a fluent DSL के बारे में एक वेबकास्ट देख रहा था और मुझे यह मानना ​​है कि मैं इस तरह के दृष्टिकोण का उपयोग क्यों करूंगा (कम से कम दिए गए उदाहरण के लिए)।डीएसएल/धाराप्रवाह इंटरफेस का बिंदु क्या है

Sizer sizer = new Sizer(); 
sizer.FromImage(inputImage) 
    .ToLocation(outputImage) 
    .ReduceByPercent(50) 
    .OutputImageFormat(ImageFormat.Jpeg) 
    .Save(); 

मैं डॉन:

वेबकास्ट है कि आप, एक इनपुट छवि उल्लेख करें कि यह आकार बदलने और निम्न सिंटैक्स का उपयोग कर एक निर्गम-फ़ाइल में सहेजें (सी # का उपयोग करके) के लिए अनुमति देता एक छवि वर्ग का आकार बदलने, प्रस्तुत 'टी समझ कैसे यह है कि कुछ मानकों लेता है एक "पारंपरिक" विधि की तुलना में बेहतर है:,

sizer.ResizeImage(inputImage, outputImage, 0.5, ImageFormat.Jpeg); 

देखने के एक प्रयोज्य दृष्टिकोण से, यह उपयोग करने के लिए बहुत आसान लगता है, के बाद से यह स्पष्ट रूप से बताता है कि विधि के रूप में की उम्मीद इनपुट।

sizer.ToLocation(outputImage).Save(); 
तो पर अपने सवालों के

: इसके विपरीत, धाराप्रवाह इंटरफेस के साथ, कुछ भी आप को छोड़ते हुए/एक पैरामीटर/विधि-कॉल भूल, उदाहरण के लिए करने से रोकता है

1 - वहाँ कुछ रास्ता है एक धाराप्रवाह इंटरफ़ेस की उपयोगिता में सुधार करने के लिए (यानी उपयोगकर्ता को बताएं कि उसे क्या करने की उम्मीद है)?

2 - क्या यह धाराप्रवाह इंटरफ़ेस दृष्टिकोण सी # में मौजूद मौजूदा नामित विधि पैरामीटर के लिए केवल एक प्रतिस्थापन है? नामित पैरामीटर अप्रचलित इंटरफेस अप्रचलित बना देंगे, उदा। कुछ इसी तरह उद्देश्य सी प्रदान करता है:

sizer.Resize(from:input, to:output, resizeBy:0.5, ..) 

3 - रहे धाराप्रवाह इंटरफेस बस के ऊपर से इस्तेमाल किया क्योंकि वे वर्तमान में लोकप्रिय हैं?

4 - या यह वेबकास्ट के लिए चुना गया एक बुरा उदाहरण था? उस स्थिति में, मुझे बताएं कि इस तरह के दृष्टिकोण के फायदे क्या हैं, इसका उपयोग करने के लिए यह कहां समझ में आता है।

बीटीडब्ल्यू: मुझे jquery के बारे में पता है, और देखें कि यह चीजों को कितना आसान बनाता है, इसलिए मैं उस या अन्य मौजूदा उदाहरणों के बारे में टिप्पणियों की तलाश नहीं कर रहा हूं।

मैं कुछ (सामान्य) टिप्पणियों को समझने में मदद करता हूं (उदाहरण के लिए) एक धाराप्रवाह इंटरफ़ेस (क्लासिकल क्लास-लाइब्रेरी के बजाए) को लागू करने के लिए, और एक को कार्यान्वित करने के लिए क्या देखना है।

+0

दिलचस्प प्रश्न –

+1

+1 मुझे यह भी लगता है कि वे वर्तमान में अधिक उपयोग कर रहे हैं। –

उत्तर

13

2 - इस धाराप्रवाह इंटरफ़ेस दृष्टिकोण सिर्फ गैर के लिए एक स्थानापन्न में सी # विधि पैरामीटर नाम वाले मौजूदा है? नामित पैरामीटर धाराप्रवाह इंटरफेस अप्रचलित बना देंगे, उदा। कुछ समान उद्देश्य-सी ऑफ़र:

ठीक है हाँ और नहीं। धाराप्रवाह इंटरफ़ेस आपको बड़ी मात्रा में लचीलापन देता है। कुछ ऐसा जो नामित पैरामीटर के साथ प्राप्त नहीं किया जा सका है:

sizer.FromImage(i) 
.ReduceByPercent(x) 
.Pixalize() 
.ReduceByPercent(x) 
.OutputImageFormat(ImageFormat.Jpeg) 
.ToLocation(o) 
.Save(); 

FromImage, ToLocation और तरल पदार्थ इंटरफ़ेस में OutputImageFormat, मेरे लिए एक सा गंध आती है। इसके बजाय मैंने इन पंक्तियों के साथ कुछ किया होगा, जो मुझे लगता है कि बहुत स्पष्ट है।

new Sizer("bob.jpeg") 
.ReduceByPercent(x) 
.Pixalize() 
.ReduceByPercent(x) 
.Save("file.jpeg",ImageFormat.Jpeg); 

Fluent इंटरफेस वही समस्या कई प्रोग्रामिंग तकनीक है, वे, दुरुपयोग किया जा सकता overused या underused है। मुझे लगता है कि जब इस तकनीक का प्रभावी ढंग से उपयोग किया जाता है तो यह एक अमीर और अधिक संक्षिप्त प्रोग्रामिंग मॉडल बना सकता है। यहां तक ​​कि स्ट्रिंगबिल्डर भी इसका समर्थन करता है।

var sb = new StringBuilder(); 
sb.AppendLine("Hello") 
.AppendLine("World"); 
2

चीजों को लागू करने का यह एक तरीका है।

ऐसी वस्तुओं के लिए जो कुछ भी नहीं करते हैं लेकिन एक ही आइटम को बार-बार जोड़ते हैं, इसके साथ वास्तव में कुछ भी गलत नहीं है। सी ++ स्ट्रीम पर विचार करें: वे इस इंटरफेस में परम हैं। प्रत्येक ऑपरेशन स्ट्रीम को फिर से लौटाता है, ताकि आप एक और स्ट्रीम ऑपरेशन को एक साथ जोड़ सकें।

यदि आप LINQ कर रहे हैं, और किसी ऑब्जेक्ट में हेरफेर कर रहे हैं, तो यह कुछ समझ में आता है।

हालांकि, आपके डिज़ाइन में, आपको सावधान रहना होगा। अगर आप आधे रास्ते से विचलित होना चाहते हैं तो व्यवहार क्या होना चाहिए?(आईई,

var obj1 = object.Shrink(0.50); // obj1 is now 50% of obj2 
var obj2 = object.Shrink(0.75); // is ojb2 now 75% of ojb1 or is it 75% of the original? 

obj2 मूल वस्तु का 75% है, तो इसका मतलब है तो था कि आप वस्तु हर बार की पूरी प्रतिलिपि बना रहे हैं (और, कई मामलों में अपने फायदे हैं, जैसा कि आप कोशिश कर रहे हैं एक ही चीज़ के दो उदाहरण बनाने के लिए, लेकिन थोड़ा अलग)।

यदि विधियां मूल वस्तु को आसानी से जोड़ती हैं, तो इस प्रकार का वाक्यविन्यास कुछ हद तक अपमानजनक होता है। वे बदले ऑब्जेक्ट को बनाने के लिए मैनिपुलेशन के बजाय ऑब्जेक्ट पर हेरफेर हैं

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

5

पर विचार करें:

sizer.ResizeImage(inputImage, outputImage, 0.5, ImageFormat.Jpeg); 

क्या होगा यदि आप कम स्पष्ट चर नाम प्रयोग किया है:

sizer.ResizeImage(i, o, x, ImageFormat.Jpeg); 

कल्पना कीजिए कि आप इस कोड को बाहर मुद्रित है। इन तर्कों का अनुमान लगाना मुश्किल है, क्योंकि आपके पास विधि हस्ताक्षर तक पहुंच नहीं है।

धाराप्रवाह इंटरफेस के साथ, यह स्पष्ट है:

sizer.FromImage(i) 
.ToLocation(o) 
.ReduceByPercent(x) 
.OutputImageFormat(ImageFormat.Jpeg) 
.Save(); 

इसके अलावा, तरीकों में से क्रम महत्वपूर्ण नहीं है। यह बराबर है:

sizer.FromImage(i) 
.ReduceByPercent(x) 
.OutputImageFormat(ImageFormat.Jpeg) 
.ToLocation(o) 
.Save(); 

इसके अलावा, शायद आप उत्पादन छवि प्रारूप के लिए डिफ़ॉल्ट हो सकता है, और कमी है, तो यह हो सकता है:

sizer.FromImage(i) 
.ToLocation(o) 
.Save(); 

यह अतिभारित आवश्यकता होगी एक ही प्राप्त करने के लिए निर्माताओं प्रभाव।

+0

इसलिए एक धाराप्रवाह इंटरफ़ेस का एक लाभ यह है कि यह पठनीय कोड सुनिश्चित करता है (जबकि इंटरफ़ेस/एपीआई की उपयोगिता के बारे में एक पारंपरिक इंटरफ़ेस अधिक हो सकता है)। – M4N

8

मैं कहूंगा कि धाराप्रवाह इंटरफ़ेस थोड़ा अधिक हो गया है और मुझे लगता है कि आपने केवल एक ऐसा उदाहरण चुना है।

जब आप इसके साथ एक जटिल मॉडल बना रहे हैं तो मुझे विशेष रूप से मजबूत धाराप्रवाह इंटरफ़ेस मिलते हैं। मॉडल के साथ मेरा मतलब है उदा। तत्काल वस्तुओं का एक जटिल संबंध। धाराप्रवाह इंटरफ़ेस डेवलपर को अर्थपूर्ण मॉडल के उदाहरणों को सही ढंग से बनाने के लिए मार्गदर्शन करने का एक तरीका है। इस तरह का एक धाराप्रवाह इंटरफ़ेस तब "व्याकरण" से मॉडल के मैकेनिक्स और रिश्तों को अलग करने का एक शानदार तरीका है जिसका उपयोग आप मॉडल बनाने के लिए करते हैं, अनिवार्य रूप से अंतिम उपयोगकर्ता से विवरणों को संरक्षित करते हैं और उपलब्ध क्रियाओं को कम कर सकते हैं, विशेष परिदृश्य

आपका उदाहरण ओवरकिल की तरह थोड़ा लगता है।

मैंने हाल ही में विंडोज फॉर्म से स्प्लिटरकॉन्टेनर के शीर्ष पर कुछ धाराप्रवाह इंटरफ़ेस किया है। तर्कसंगत रूप से, नियंत्रण के पदानुक्रम का अर्थात् मॉडल सही ढंग से निर्माण करने के लिए कुछ जटिल है। एक छोटी धाराप्रवाह एपीआई प्रदान करके एक डेवलपर अब घोषणा कर सकता है कि उसके स्प्लिटरकंटनर को कैसे काम करना चाहिए। प्रयोग चला जाता है

तरह
var s = new SplitBoxSetup(); 
s.AddVerticalSplit() 
.PanelOne().PlaceControl(()=> new Label()) 
.PanelTwo() 
.AddHorizontalSplit() 
.PanelOne().PlaceControl(()=> new Label()) 
.PanelTwo().PlaceControl(()=> new Panel()); 
form.Controls.Add(s.TopControl); 

मैं अब क्रियाओं कि हाथ में इस मुद्दे के लिए प्रासंगिक हैं के एक जोड़े के लिए नियंत्रण पदानुक्रम के जटिल यांत्रिकी कम कर दिया है।

आशा इस मदद करता है

2

आप एरिक इवांस द्वारा Domain Driven Design पढ़ना चाहिए कुछ विचार क्यों डीएसएल अच्छे डिजाइन विकल्प माना जाता है पाने के लिए।

पुस्तक अच्छे उदाहरणों, सर्वोत्तम अभ्यास सलाह और डिजाइन पैटर्न से भरी है। अत्यधिक सिफारिशित।

1

वैकल्पिक पैरामीटर के कुछ संयोजनों को लागू करने के लिए फ्लुएंट इंटरफ़ेस पर भिन्नता का उपयोग करना संभव है (उदाहरण के लिए कि समूह से कम से कम एक पैरामीटर मौजूद है, और आवश्यकता है कि यदि कोई निश्चित पैरामीटर निर्दिष्ट किया गया है, तो कुछ अन्य पैरामीटर होना चाहिए छोड़े गए)। उदाहरण के लिए, कोई Enumerable.Range जैसा कार्यक्षमता प्रदान कर सकता है, लेकिन IntRange.From (5)। सिंटैक्स (1 9) या IntRange.From (5) के साथ एक वाक्यविन्यास के साथ। LessThan (10) .Stepby (2) या IntRange (3) .Count (19) .StepBy (17)। अत्यधिक जटिल पैरामीटर आवश्यकताओं के संकलन-समय प्रवर्तन के लिए मध्यवर्ती-मूल्य संरचनाओं या कक्षाओं की परेशान संख्या की परिभाषा की आवश्यकता हो सकती है, लेकिन कुछ मामलों में दृष्टिकोण सरल मामलों में उपयोगी साबित हो सकता है।

0

@sam-saffron 'जब एक नया आपरेशन जोड़ने एक सुविज्ञ इंटरफेस के लचीलेपन के बारे में रों सुझाव: यदि हम इस तरह के Pixalize(), तो के रूप में एक नया आपरेशन, जोड़ने के लिए की जरूरत

, में' के लिए आगे कई के साथ विधि पैरामीटर 'परिदृश्य, इसे विधि हस्ताक्षर में जोड़ने के लिए एक नया पैरामीटर की आवश्यकता होगी। इसके बाद इस नए पैरामीटर के लिए मूल्य जोड़ने के लिए कोडबेज में इस विधि के प्रत्येक आमंत्रण में संशोधन की आवश्यकता हो सकती है (जब तक कि उपयोग में आने वाली भाषा वैकल्पिक पैरामीटर की अनुमति न दे)।

इसलिए, फ्लुएंट इंटरफ़ेस का एक संभावित लाभ भविष्य में परिवर्तन के प्रभाव को सीमित कर रहा है।

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