اذهب إلى المحتوى

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

الأخطاء السبع القاتلة.jpg

الأنماط المضادة

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

وبالتالي، فإن النمط المضاد هو طريقة مقبولة تقنيًا لتصميم الأشياء التي يُتفق عليها عمومًا أنها خاطئة. هناك العديد من الأنماط المضادة (anti-pattern) في كل لغة. وجودها في منتجك يشبه وجود الورم في الكائن الحي. بمجرد أن يبدأ في النمو، يصبح من الصعب جدًا إيقافه. وفي النهاية، يموت الجسم بأكمله. في النهاية، يصبح البرنامج بأكمله غير قابلِ للإصلاح ويجب إعادة كتابته.

بمجرد السماح لبعض الأنماط المضادة في المنتج، ستحصل في النهاية على المزيد منها، وسينمو "الورم" فقط.

يعدُّ هذا صحيح خاصةً بالنسبة للغات البرمجية كائنية التوجه (Java، و C ++، و Ruby وPython) ويرجع ذلك غالبًا إلى أنها ترث العديد من اللغات الإجرائية (C، Fortran وCOBOL) ولأن مطوري OOP يميلون للتفكير بطريقة إجرائية وضرورية. على كلّ حال، بالإضافة إلى قائمة الأنماط المضادة المعروفة الموجودة، أنا أعدّ أيضًا أنَّ هذه الأشياء القليلة منهجيات تشفير سيئة. اقتراحي العملي الوحيد هنا هو القراءة والتعلّم. ربما تساعدك هذه الكتب أو كتاب "Elegant Objects" في ذلك. حاول دائمًا أن تشك في جودة برنامجك، ولا تكتفي بأن "يعمل فقط". كما هو الحال مع السرطان، كلما تم تشخيصه أبكر، كانت فرصة النجاة أكبر.

تغييرات لا يمكن تعقبها

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

استخدم الملاحظات دائمًا

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

أضف مراجعًا للملاحظات في الإيداعات

لا داعٍ للقول أنّه يجب أن يكون لكل إيداع (commit) رسالة. الالتزامات بدون رسائل تعتبر ممارسة سيئة جداً؛ لن أناقش لماذا. ولكن الرسالة بمفردها لا تعد كافية. يجب أن تبدأ كل رسالة برقم الملاحظة التي تعمل عليها. سيقوم GitHub (أنا متأكد من أنك تستخدمه) بربط الالتزامات والملاحظات تلقائيًا، مما يزيد من إمكانية تتبع التغييرات.

لا تحذف أي شيء

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

الإصدارات المخصصة

يجب أن يُحزَّم كل جزء من البرنامج قبل أن يتم تسليمه إلى المستخدم النهائي. إذا كنت تتعامل مع مكتبة جافا، فيجب أن تُحزَّم كملف ‎.jar ويتم تصديرها إلى مستودع ما؛ إذا كان تطبيق ويب، فيجب نشره على المنصة، وما إلى ذلك. بغض النظر عن صغر حجم المنتج أو كِبره، فهناك دائمًا إجراء معياري يختبر ويُحزِّم وينشر.

سيكون الحل المثالي هو أتمتة هذا الإجراء بحيث يكون من الممكن تنفيذه من سطر الأوامر باستخدام أمر واحد

$ ./release.sh
...
DONE (took 98.7s)

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

يمكنني هنا تقديم نصيحة عملية واحدة فقط: "الأتمتة"، أنا أستخدم rultor.com من أجل ذلك، لكن يمكنك استخدام أي أدوات تريدها. المهم أن يكون الإجراء بأكمله مؤتمتًا بالكامل ويمكن تنفيذه من سطر الأوامر.

تحليل ثابت طوعي

التحليل الثابت هو ما يجعل شيفرتنا تبدو أفضل. وبجعلها تبدو أفضل، فإننا حتمًا نجعلها تعمل بشكل أفضل. لكن هذا يحدث فقط عندما يضطر الفريق بأكمله إلى اتباع القواعد التي يحددها المحلل (أو المحللون) الثابت (static analyzer). لقد كتبت عن ذلك في التحكم الصارم لجودة شيفرة الجافا. يمكنني استخدام qulice.com في مشاريع Java و rubocop.com في Ruby، وهناك العديد من الأدوات المشابهة لكل لغة تقريبًا.

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

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

تغطية اختبار غير معروف

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

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

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

تطوير دون توقف

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

هذا في الغالب لأن الصيانة تدور حول القدرة على الفهم عند قراءة شيفرتك.

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

وسوم Git وملاحظات إصدار Github هما أداتان قويتان توفران لي هذه المعلومات. استخدمها إلى أقصى حد. ولا تنسَ أن كل إصدار ثنائي للمنتج يجب أن يكون متاحًا للتحميل المباشر. يجب أن أكون قادرًا على تنزيل الإصدار 0.1.3 واختباره مباشرةً، حتى لو كان المشروع يعمل على الإصدار 3.4 في الوقت الحالي.

الواجهات غير الموثّقة

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

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

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

إذا كان برنامجك عبارة عن مكتبة، فإن مستخدميها النهائيين الذين سيستخدمونها هم من مطوري البرامج - لا يساهمون فيها ولكن يستخدمونها ببساطة كـ"الصندوق الأسود".

هذه هي المعايير المستخدمة لتقييم المشاريع المفتوحة المصدر التي دخلت المنافسة على الجائزة لدينا.

ترجمة -وبتصرف- للمقال Seven Deadly Sins of a Software Project لصاحبه Yegor Bugayenko.


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...