DanLevy.net

احذر أحاديي الهدف

نقي لدرجة الألم

مبدأ المسؤولية الواحدة هو أحد تلك الأفكار التي تبدو منطقية لدرجة أنها قد تتسلل عبر حكمك.

افعل شيئًا واحدًا. افعله جيدًا. حافظ على تركيز الوحدات. أعط الكود سببًا للتغيير. نصيحة جيدة.

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

المشكلة ليست في SRP. المشكلة هي التعامل مع “الصغر” كبديل عن “التماسك”.

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

العنف في هندسة البرمجيات
مكونات، مكونات في كل مكان

I. الفكرة المفيدة الكامنة

إضافة خانة اختيار واحدة إلى نموذج يجب أن تؤثر من الناحية المثالية على ملف واحد فقط. ليس 8 ملفات عبر 5 أدلة… أنا أنظر إليك، React/Redux.

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

حتى الأمثلة الكلاسيكية لـ Unix هي أكثر عملية مما يوحي به الشعار. ls يسرد الملفات، نعم، لكنه أيضًا ينسق استدعاءات مثل opendir و readdir و closedir و stat. الوحدة المفيدة ليست أصغر عملية ممكنة. الوحدة المفيدة هي أصغر شيء متماسك يحل المهمة.

فلسفة يونكس الأصلية كانت حول التركيب و البساطة، وليس حول اختزال كل شيء إلى دالة أو ملف واحد.

هذا الفرق مهم. “مسؤولية واحدة” ليست نفس “سطر واحد من السلوك”.

II. الإفراط في التجريد: عندما تتحول البساطة إلى فوضى

مهندسنا المعماري يصر على أن أي دالة أطول من 5 أسطر هي ‘رائحة كود’. قاعدة الكود لدينا الآن تفوح منها رائحة اليأس الخالي من الحيلة.

نمط الفشل سهل الاكتشاف بعد أن جعل أسبوعك أسوأ بالفعل.

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

لا مفر من نمط العمل اللانهائي هذا
مكونات، مكونات في كل مكان

ماذا اشترى كل ذلك النقاء؟

لقد حدقت في هاوية قواعد الكود حيث تم تشريح ميزة بسيطة من 100 سطر عبر أكثر من 15 ملفًا، كل منها ملاك صغير “نقي” يحتوي ربما على دالة أو اثنتين. نصف قطر الانفجار المعرفي لمحاولة حمل تلك الفوضى في رأسك ألغى تمامًا أي مكسب نظري من الفصل. لم تكن أبسط؛ كانت فقط مبعثرة.

III. ثمن الكمال: الأثر على المطورين

نقضي وقتًا أطول في النقاش حول هيكلة الملفات واتفاقيات التسمية مقارنةً بتسليم الميزات. هل هذا هو الرشيق؟

فوضى تكاد تكون فنًا
فوضى تكاد تكون فنًا

هذا التفتت المرضي ليس مجرد مشكلة جمالية. إنه يغير كيفية إنفاق المطورين لانتباههم:

استنزاف الإنتاجية: انسَ الديون التقنية؛ هذا دين تنظيمي متراكم عبر تداخل الدلائل القهري. كل تعديل بسيط يتحول إلى حفريات أثرية عبر طبقات التجريد. يتبخر الوقت في الثقب الأسود لـ cd .. و grep.

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

الحمل المعرفي: هناك حد صارم لعدد القطع المنفصلة من المعلومات التي يمكن للعقل البشري التعامل معها. إجبار المطورين على تجميع تدفق البرنامج من عشرات الملفات المبعثرة يعيق الفهم بنشاط ويجعل التغييرات الواثقة أصعب.

IV. تبني البراغماتية: بديل عملي

اقترحت وضع دالتين مترابطتين في نفس الملف. كان رد فعل الغرفة وكأنني اقترحت حذف بيئة الاختبار. — قارئ متعافٍ من النقاء

مخرج الطوارئ ليس التخلي عن مبدأ المسؤولية الواحدة. الإجابة هي تطبيقه على المستوى الصحيح من المعنى.

إليك ما يبدو عليه ذلك عمليًا:

الهدف ليس الكمال النظري الذي يستحق أطروحة دكتوراه؛ بل إنشاء كود يستطيع زملاؤك (وأنت في المستقبل) التنقل فيه وفهمه وتعديله دون أن ترغب في إشعال النار في المبنى.

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

ابقَ مركزًا بلا هوادة على الأسئلة العملية:

خامسًا: الخاتمة: تعزيز الكود المتماسك والقابل للصيانة

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

لذا عندما تصادف “أشخاص الغرض الواحد”، المستعدين لشن حرب على أي دالة تجرؤ على تجاوز ثلاثة أسطر، خذ نفسًا. تذكّر خانة الاختيار ذات الـ12 ملفًا.

مهمتنا ليست بناء دوال ثلجية نقية نظريًا. مهمتنا هي بناء برمجيات تعمل، وتحل المشكلات، ولا تعاقب الشخص التالي الذي سيتعامل معها.

ابقَ عمليًا. ركّز على النتائج. لا تدع السعي وراء النقاء المثالي يصبح عدوًا للكود القابل للصيانة. سلامتك العقلية، وسرعة فريقك، تعتمدان على ذلك.

المفارقة هي أن تحقيق الغرض الواحد الفعلي على أدنى المستويات يتطلب تعقيدًا هائلًا مخفيًا تحت السطح مباشرة.¹

نحن نتحدث عن النقاء المفاهيمي هنا: فكرة أن الدالة يجب أن تفعل “شيئًا واحدًا” فقط منطقيًا. لا تخلط بين هذا وبين مفهوم “الدالة النقية” في البرمجة الوظيفية التي لا تحتوي على آثار جانبية، فهي فكرة مختلفة، وإن كانت مرتبطة أحيانًا.