سؤال

كنت أشاهد مؤخرا على البث الشبكي كيفية إنشاء DSL بطلاقة ولدي الاعتراف، أنا لا أفهم الأسباب التي تجعل المرء يستخدم مثل هذا النهج (على الأقل للمثال المحدد).

قدمت البث الشبكي فئة تغيير حجم الصورة، تتيح لك تحديد صورة إدخال، تغيير حجمها وحفظها إلى ملف إخراج باستخدام بناء الجملة التالي (باستخدام C #):

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 - هل هذا هو نهج الواجهة بطلاقة باستبدال لمعلمات الأسلوب غير المسماة غير الموجودة في C #؟ من شأنه أن يدعى المعلمات تجعل واجهات بطلاقة عفا عليها الزمن، مثل عرض شيء مشابه

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

3 - واجهات بطلاقة أكثر من استخدامها ببساطة لأنها تحظى بشعبية حاليا؟

4 - أو هل كان مجرد مثال سيء تم اختياره للبث عبر الإنترنت؟ في هذه الحالة، أخبرني ما هي مزايا هذا النهج، أين من المنطقي استخدامه.

راجع للشغل: أعرف عن jQuery، ونرى مدى سهولة تشغيل الأشياء، لذلك أنا لا أبحث عن تعليقات حول ذلك أو غيرها من الأمثلة الحالية.

أنا أكثر تبحث عن بعض التعليقات (عامة) لمساعدتي في فهم (على سبيل المثال) عند تنفيذ واجهة بطلاقة (بدلا من مكتبة فئة كلاسيكية)، وما الذي يجب مراقبته عند تنفيذ واحد.

هل كانت مفيدة؟

المحلول

2 - هل نهج الواجهة بطلاقة هذا مجرد بديل لمعلمات الطريقة غير الموجودة المسماة في C #؟ من شأنه أن يدعى المعلمات تجعل واجهات بطلاقة عفا عليها الزمن، مثل عرض شيء مشابه

حسنا نعم ولا. واجهة بطلاقة تمنحك كمية أكبر من المرونة. شيء لا يمكن تحقيقه مع المعالم المسماة هو:

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

the fromisage، toolocation and outpureimageformat في واجهة السوائل، رائحة بعض الشيء بالنسبة لي. بدلا من ذلك، كنت قد فعلت شيئا على هذه الخطوط، والتي أعتقد أنها أكثر وضوحا.

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

تتضمن واجهات بطلاقة نفس المشكلات لديها العديد من تقنيات البرمجة، ويمكن إساءة استخدامها أو غير مستعص عليها أو غير مستعبة. أعتقد أنه عندما يتم استخدام هذه التقنية بشكل فعال، يمكن أن تخلق نموذج برمجة أكثر ثراء وأكثر إيجازا. حتى Stringbuilder يدعم ذلك.

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

نصائح أخرى

أود أن أقول إن واجهات بطلاقة مبالغ فيها قليلا وأعتقد أنك اخترت مثالا فقط من هذا القبيل.

أجد واجهات بطلاقة قوية خاصة عندما تقوم بإنشاء نموذج معقد معه. مع نموذج أعني مثل علاقة معقدة من كائنات مثيل. واجهة بطلاقة هي وسيلة لتوجيه المطور إلى بناء مثيلات النموذج الدلالي بشكل صحيح. هذه الواجهة بطلاقة ستكون وسيلة ممتازة لفصل ميكانيكا وعلاقات نموذج من "القواعد" التي تستخدمها لإنشاء النموذج، وتفاصيل التدريع بشكل أساسي من المستخدم النهائي وتقليل الأفعال المتاحة إلى أن تلك ذات الصلة فقط في سيناريو معين.

مثالك يبدو قليلا مثل المبالغة.

لقد قمت بذلك مؤخرا ببعض الواجهة بطلاقة أعلى من SplitterContainer من نماذج Windows. يمكن القول أن النموذج الدلالي لتسلسل الضوابط الهرمي هو مجمع إلى حد ما للبناء بشكل صحيح. من خلال توفير API بطلاقة صغيرة، يمكن للمطور الآن التعبير عن كيفية عمل SplitterContainer الخاص به. الاستخدام يذهب مثل

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);

لقد خفضت الآن الميكانيكا المعقدة للتسلسل الهرمي للتحكم في الأفعال ذات الصلة بالقضية في متناول اليد.

أتمنى أن يساعدك هذا

انصح:

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();

هذا سيتطلب منشئين مثقلين لتحقيق نفس التأثير.

إنها طريقة واحدة لتنفيذ الأشياء.

بالنسبة للكائنات التي لا تفعل شيئا سوى التعامل مع نفس العنصر مرارا وتكرارا، لا يوجد شيء خاطئ حقا في ذلك. النظر في تدفقات C ++: إنها في نهاية المطاف في هذه الواجهة. إرجاع كل عملية التدفق مرة أخرى، حتى تتمكن من إجراء عملية دفق أخرى معا.

إذا كنت تقوم بتنفيذ 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٪ من الكائن الأصلي، فهذا يعني أنك تقوم بنسخة كاملة من الكائن في كل مرة (ولديها مزاياها في كثير من الحالات، كما لو كنت تحاول إجراء مثيلتين من نفس الشيء، ولكن بشكل مختلف قليلا).

إذا كانت الأساليب ببساطة معالجة الكائن الأصلي، فإن هذا النوع من بناء الجملة هو مخادع إلى حد ما. تلك هي التلاعب على الكائن بدلا من التلاعب لإنشاء كائن تغيير.

ليس كل فصول العمل مثل هذا، ولا معنى لها القيام بهذا النوع من التصميم. على سبيل المثال، سيكون لهذا النمط للتصميم ليس فائدة فائدة في تصميم برنامج تشغيل الأجهزة أو جوهر تطبيق واجهة المستخدم الرسومية. طالما أن التصميم ينطوي على شيء سوى التلاعب ببعض البيانات، فإن هذا النمط ليس سيئا.

يجب أن تقرأ Domain Driven Design بواسطة إريك إيفانز للحصول على بعض الفكرة لماذا يعتبر DSL اختيار تصميم جيد.

الكتاب مليء بالأمثلة الجيدة وأفضل نصائح الممارسات وأنماط التصميم. ينصح به بشده.

من الممكن استخدام الاختلاف على واجهة بطلاقة لإنفاذ مجموعات معلمات اختيارية (على سبيل المثال، تتطلب معلمة واحدة على الأقل من مجموعة موجودة، وتتطلب ذلك إذا تم تحديد معلمة معينة، فيجب حذف بعض المعلمات الأخرى). على سبيل المثال، يمكن للمرء أن يوفر وظيفة مماثلة لعملية .range، ولكن مع بناء جملة مثل Intrange.from (5) أو intrange (19) أو intrange.from (5). 3) .count (19) .stepby (17). قد يتطلب تطبيق تجميع الوقت لمتطلبات المعلمات المفرطة المعقدة تعريف عدد مزعج من الهياكل أو الطبقات المتوسطة القيمة، ولكن يمكن أن يكون النهج في بعض الحالات مفيدا في حالات أبسط.

علاوة على ذلك @ سام الزعفراناقتراح بخصوص مرونة واجهة بطلاقة عند إضافة عملية جديدة:

إذا كنا بحاجة إلى إضافة عملية جديدة، مثل Pixalize ()، فعندئذ، في "الطريقة" مع سيناريو معلمات متعددة، سيتطلب ذلك معلمة جديدة تضاف إلى توقيع الطريقة. قد يتطلب ذلك بعد ذلك إجراء تعديلا لكل استدعاء لهذه الطريقة في جميع أنحاء CodeBase لإضافة قيمة لهذه المعلمة الجديدة (ما لم تسمح اللغة المستخدمة بمعلمة اختيارية).

وبالتالي، فإن الفائدة المحتملة لواجهة بطلاقة تحد من تأثير التغيير في المستقبل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top