سؤال

واحدة من الأكثر شيوعا الحجج أسمع لعدم الالتزام خالص مبادئ في تصميم وجوه المنحى هو YAGNI (على الرغم من أن نسبة سرعة الرياح درجة الحرارة في كثير من الأحيان لا نسميها):

"فلا بأس أن أضع كل ميزة X و ميزة Y في نفس الفئة.بل هو في غاية البساطة لماذا تهتم إضافة فئة جديدة (أيالتعقيد)."

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

"إذا كان في حالة غير المحتمل الجديدة متطلبات قانون بلدي يحصل تشوش أيضا ما زلت لا أستطيع أن ريفاكتور عن الشرط الجديد.حتى ما إذا كنت بحاجة إلى وقت لاحق...' حجة لا يحتسب."

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

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

المحلول

التصميم هو إدارة وتوازن المقايضات. yagni والصلبة ليست متضاربة: يقول الأول متى لإضافة ميزات ، يقول الأخير كيف، لكن كلاهما يوجه عملية التصميم. تستخدم ردودي ، أدناه ، لكل من اقتباساتك المحددة مبادئ من كل من Yagni و Solid.

  1. يصعب بناء مكونات قابلة لإعادة الاستخدام ثلاث مرات مثل مكونات الاستخدام الفردي.
  2. يجب تجربة المكون القابل لإعادة الاستخدام في ثلاثة تطبيقات مختلفة قبل أن يكون عامًا كافياً لقبول مكتبة إعادة الاستخدام.

- روبرت جلاس قواعد ثلاثة, حقائق ومغالطات هندسة البرمجيات

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

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


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

هل هي حقا واجهة المستخدم الوحيدة؟ هل يوجد وضع دفعة في الخلفية مخطط له؟ هل ستكون هناك واجهة ويب؟

ما هي خطة الاختبار الخاصة بك ، وهل ستختبر وظائف النهاية الخلفية بدون واجهة المستخدم الرسومية؟ ما الذي سيجعل واجهة المستخدم الرسومية سهلة الاختبار ، نظرًا لأنك عادة لا ترغب في اختبار الكود الخارجي (مثل عناصر التحكم في واجهة المستخدم الرسومية من النظام الأساسي) وبدلاً من ذلك تركز على مشروعك.

من الجيد أن أضع ميزة X وميز y في نفس الفصل. إنه أمر بسيط للغاية لماذا تهتم بإضافة فئة جديدة (أي تعقيد).

هل يمكنك الإشارة إلى خطأ شائع يجب تجنبه؟ بعض الأشياء بسيطة بما فيه الكفاية ، مثل تربيع رقم (x * x ضد squared(x)) للحصول على مثال بديل بشكل مفرط ، ولكن إذا تمكنت من الإشارة إلى خطأ ملموس ارتكبه شخص ما-خاصة في مشروعك أو من قبل أولئك الموجودين في فريقك-يمكنك إظهار كيف أن فئة أو وظيفة مشتركة ستتجنب ذلك في المستقبل.

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

المشكلة هنا هي افتراض "غير مرجح". هل توافق على أنه من غير المحتمل؟ إذا كان الأمر كذلك ، فأنت متفق مع هذا الشخص. إذا لم يكن الأمر كذلك ، فإن فكرتك عن التصميم لا تتفق مع هذا الشخص - حل هذا التناقض سيحل المشكلة ، أو على الأقل يوضح لك إلى أين تذهب بعد ذلك. قون

نصائح أخرى

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

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

أحب أن أفكر في Yagni من حيث "النصف ، وليس نصف الحواس" ، لاستعارة العبارة من 37Signals (https://gettingreal.37signals.com/ch05_half_not_half_assed.php). يتعلق الأمر بالحد من نطاقك حتى تتمكن من التركيز على القيام بأهم الأشياء بشكل جيد. إنه ليس ذريعة للحصول على قذرة.

منطق العمل في واجهة المستخدم الرسومية يشعر نصف حافز بالنسبة لي. ما لم يكن نظامك تافهًا ، سأفاجأ إذا لم يتغير منطق عملك و GUI بشكل مستقل بالفعل ، عدة مرات قد انتهى. لذلك يجب عليك اتباع SRP ("S" في Solid) و Refactor - Yagni لا ينطبق ، لأنك في حاجة إليها بالفعل.

تنطبق الحجة حول Yagni والتعقيد غير الضروري تمامًا إذا كنت تقوم بعمل إضافي اليوم لاستيعاب متطلبات المستقبل الافتراضية. عندما تفشل تلك السيناريوهات "ماذا لو احتجت فيما بعد ..." في تحقيقها ، فأنت عالق مع تكاليف الصيانة الأعلى من التجريدات التي تعيق الآن التغييرات التي لديك بالفعل. في هذه الحالة ، نتحدث عن تبسيط التصميم عن طريق الحد من النطاق-القيام بالنصف ، بدلاً من أن نكون نصفهم.

لا توجد إجابة ، أو بالأحرى ، لا توجد إجابة لا ترغب أنت أو محاورك: يمكن أن يكون كل من Yagni و Solid أساليب خاطئة.

إن محاولة الذهاب إلى الصلبة مع فريق عديمي الخبرة ، أو فريق ذو أهداف ضيقة إلى حد كبير ، يضمن أنك ستنتهي بمجموعة من الكود باهظ الثمن ، والتي لن تكون صلبة ، ومصبح أكثر من الهندسة (ويعرف أيضًا باسم Welcome إلى العالم الحقيقي).

محاولة الذهاب إلى Yagni لمشروع طويل الأجل وآمل أن تتمكن من إعادة تشكيلها لاحقًا إلى حد ما (المعروف أيضًا باسم مرحبًا بك في العالم الحقيقي). يتفوق Yagni في إثبات المفاهيم والمظاهرين ، ويحصل على السوق/العقد ثم يكون قادرًا على الاستثمار في شيء أكثر صلابة.

أنت بحاجة إلى كليهما ، في نقاط مختلفة في الوقت المناسب.

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

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

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

صحيح أنه يمكنك إعادة تشكيله لاحقًا. النقطة المهمة هي في الواقع هل إعادة البناء. لذلك أعتقد أن المشكلة الحقيقية ليست حل وسط التصميم في بعض الأحيان ، ولكن تأجيل إعادة إعادة البناء بمجرد أن يصبح من الواضح أن هناك مشكلة. في الواقع يمر به هو الجزء الصعب (تمامًا كما هو الحال مع العديد من الأشياء في الحياة ...).

فيما يتعلق بنقاطك الفردية:

من الجيد أن أضع ميزة X وميز y في نفس الفصل. إنه أمر بسيط للغاية لماذا تهتم بإضافة فئة جديدة (أي تعقيد).

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

لا تخف من الطبقات الصغيرة ، فهي لا تعض ؛-).

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

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

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

هذا له بعض الجدارة ، ولكن فقط إذا قاموا بالفعل بإعادة الطرد لاحقًا. لذا اقبله ، واحتفظ بهم على وعدهم :-).

تسمح المبادئ الصلبة للبرنامج بالتكيف مع التغيير - في كل من المتطلبات والتغييرات الفنية (المكونات الجديدة ، إلخ) ، وهما من وسيطاتك لمتطلبات غير متغيرة:

  • "من غير المرجح أن تأتي متطلبات جديدة من Signifcant."
  • "إذا كان في حالة متطلبات جديدة غير محتملة"

يمكن أن يكون هذا حقا صحيح؟

لا يوجد بديل عن الخبرة عندما يتعلق الأمر بنفقات التنمية المختلفة. بالنسبة للعديد من الممارسين ، أعتقد أن القيام بالأشياء في الرديئة ، من الصعب الحفاظ على الطريقة لم يؤدي أبدًا إلى مشاكل بالنسبة لهم (مهلا! الأمن الوظيفي). على المدى الطويل من المنتج ، أعتقد أن هذه النفقات تصبح واضحة ، لكن القيام بشيء عنها في وقت مبكر هو وظيفة شخص آخر.

هناك بعض الإجابات الرائعة الأخرى هنا.

من المفهوم والمرن والقادر على الإصلاحات والتحسينات دائمًا أشياء نكون سوف تحتاج. في الواقع ، يفترض Yagni أنه يمكنك العودة وإضافة ميزات جديدة عندما يثبت ضروريًا بسهولة نسبية ، لأن لا أحد يفعل شيئًا مجنونًا مثل الوظيفة غير ذات الصلة في الفصل (Yagni في تلك الفئة!) .

يمكن أن تكون هناك أوقات كان فيها ما يبدو مجنونًا الآن معقولًا في الماضي - في بعض الأحيان ، فإن خطوط حدود واجهة المستخدم أو بين مجموعات مختلفة من المسؤوليات التي يجب أن تكون في فئة مختلفة ليست واضحة ، أو حتى تتحرك. يمكن أن تكون هناك أوقات يكون فيها 3 ساعات من العمل ضرورية للغاية في غضون ساعتين. هناك أوقات لا يقوم فيها الناس بالمكالمة الصحيحة. لتلك الأسباب ، ستحدث فترات راحة عرضية في هذا الصدد ، لكنهم سيعيقون استخدام مبدأ Yagni ، وليس سببًا له.

اختبارات وحدة الجودة ، وأعني اختبارات الوحدة لا اختبارات التكامل ، تحتاج إلى رمز يلتزم بالصلبة. ليس بالضرورة 100 ٪ ، في الواقع نادرًا ما ، ولكن في مثالك ، فإن حشو ميزتين في فصل واحد سيجعل اختبار الوحدة أكثر صعوبة ، ويحطم مبدأ المسؤولية الفردية ، ويجعل صيانة التعليمات البرمجية من قبل فريق Newbies أكثر صعوبة (حيث يصعب فهمها) .

من خلال اختبارات الوحدة (على افتراض تغطية رمز جيدة) ، ستتمكن من إعادة تشكيل ميزة 1 آمنة ومأمونة ، ولن تكسر الميزة 2 ، ولكن بدون اختبارات الوحدة ومع الميزات في نفس الفئة (ببساطة أن تكون كسولًا في مثالك) إعادة البناء محفوفة بالمخاطر في أحسن الأحوال ، كارثية في أحسن الأحوال.

خلاصة القول: اتبع مبدأ KIS (تبقيه بسيطًا) ، أو للمبدأ الفكري للمبدأ (KIS غبي). خذ كل حالة على الجدارة ، لا توجد إجابة عالمية ولكنها دائمًا ما تنظر فيما إذا كان المبرمجين الآخرون بحاجة إلى قراءة / الحفاظ على الكود في المستقبل واستفادة من اختبارات الوحدة في كل سيناريو.

tldr;

خالص يفترض أنك تفهم (إلى حد ما على الأقل), المستقبل تغييرات على قانون ، wrt SRP.أقول هذا هو التفاؤل حول القدرة على التنبؤ.YAGNI من ناحية أخرى ، يفترض معظم الأوقات أنت لا تعرف المستقبل اتجاه التغيير ، وهو التشاؤم حول قدرة على التنبؤ.

وبالتالي فإنه يترتب على ذلك الصلبة/SRP يطلب منك شكل فصول رمز هذه أنه سيكون لديك سبب واحد من أجل التغيير.E. g.صغيرة واجهة المستخدم الرسومية تغيير أو ServiceCall تغيير.

YAGNI يقول (إذا كنت ترغب في فرض تطبيقه في هذا السيناريو), منذ كنت لا تعرف ما هو الذهاب الى تغيير ، وإذا كان المستخدم الرسومية التغيير سيكون سببا في واجهة المستخدم الرسومية+ServiceCall تغيير (وبالمثل الخلفية مما تسبب في تغيير واجهة المستخدم الرسومية+SeviceCall تغيير) ، ضع كل رمز في صنف واحد.

الجواب طويل :

قراءة كتاب 'تطوير البرمجيات رشيق والمبادئ أنماط وممارسات'

أنا أضع مقتطفات قصيرة من ذلك عن صلب/SRP :"إذا,[...]تطبيق لا تغيير في الطرق التي تسبب اثنين من المسؤوليات إلى تغيير في أوقات مختلفة ، هناك حاجة إلى فصل لهم.والواقع أن يفصل لهم أن رائحة وغني عن التعقيد.

هناك corrolary هنا.محور التغيير هو محور التغيير إلا إذا تحدث التغييرات.ليس من الحكمة أن تطبيق SRP—أو أي مبدأ آخر ، إذا كان هناك أي أعراض."

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