23

ما هي معايير جودة البرمجة او المبرمج ؟

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

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

كذلك يجب على الكود ان يكون اقتصادي بحيث لا يستهلك الكثير من موارد النظام ( RAM الذاكرة، وحدة المعالجة المركزية CPU ، وما إلى ذلك) بحيث يوفر التكاليف لانه اذا كان الكود يكلف الكثير من الموارد للتشغيل فهذا سوف يجعل التكلفة الاقتصادية كبيرة مما يؤدة بالمستثمر الى الغاء المشروع اذا كان العائد لا يغطي التكاليف وبالتالي يؤدي في النهاية الى فشل المشروع

اترك المجال للاعضاء لإضافة معايير أخرى


30

في الغالب الكود الجيد هو:

الذي يكون قابل للصيانه Maintainability

هو الذي يطبق معايير الحمايه بشكل جيد الSecure Code

الكود الأقل استهلاك لموارد النظام Most Efficient

هو الكود الذي لا يعيد اختراع العجلة ويستخدم ال libraries المتوفرة بقدر الإمكان

الصيانه هي من الأمور المهمه بالنسبة للمبرمج العادي :

وهي لها اكثر من مسار تستطيع عمله حتى يكون كودك أفضل، سواء جعلته أكثر مقروئية Readability أو يسهل العمل والاضافه عليه Extensible أو الذي يفحص مدخلاته جيداً Robustness Code والذي يسهل اختباره Testability..

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

وقد تصل للمقروئية الجيدة في حال اتبعت التسميات الجيدة والتي فيها الغالب لكل لغه Convention خاص بها ، وايضاً اذا استخدمت بعض ال Patterns لكي تحسن الAPI لديك، على سبيل المثال لماذا تقوم بعمل دالة بناء تستقبل 20 مدخل ؟ فلم لا تكبسلها Encapsulated مثلاً ؟ أو تستخدم Builder Pattern أو Static Factory ؟

من الطرق للوصول لل Maintainability هي عن جعل الدوال والكلاسات لديك مسؤولة عن شيء واحد فقط Single Responsibility وهكذا لن تكون مضطر لتغيير تلك الأمور الا لسبب واحد فقط..

ايضاً كلما حولت مشروعك لفكرة ال Modules ) Layers أو Packages أو Namespaces ) وقللت التداخل Coupling بين تلك الوحدات وأخفيت كل شي بقدر الامكان Hide Implementation كلما جعلته اكثر قابلية للصيانه ، لذلك نقول (لا تستخدم public الا عندما تحتاجها فقط):

بالنسبة للبقية Extensibility وال Testability ففي الغالب تستطيع الوصول لتلك الخصائص عندما تجعل مشروع يقوم على فكرة الInterface-Based Design ، بمعنى عندما تصمم كلاس يتعامل مع القاعدة اجعله يطبق Interface معينة، ويرجع Business Domain ما، والسبب أنك ربما قد تحتاج لجعل البرنامج يتعامل مع data source أخرى وهنا سوف تقوم بتطبيق نفس ال Interface وهكذا البرنامج سوف يتطور بدون تغيير، وفي نفس الوقت قد تقوم بعمل Mock للdata access هذه وتقوم باستخدمها في unit test حتى تتأكد من عمل الطبقة التي تتعامل مع هذه الdata access

لو نظرت اعلاه ستجد أننا استخدمنا OO Principles والحق يقال كلما استخدمتها بشكل جيد كلما وصلت لكود جيد أيضاً، والحقيقة المرة أن تطبيق الOO بشكل جيد صعب ويحتاج لدراسه (وأقصد كتابه كائنات تقوم بالBusiness مثلاً EbookParser أو TaskSchedular أو PaymentProcessor وليس فقط Employee أو Animal والخ من هذه ال Business Objects) فكثير ما يخطئ المبتدئين عندما يستخدموا OO Language ويقوموا بعمل بضعه Concept Objects ويظن أن هذه هي الOO ولكن الحقيقه هو أنه استخدم Objects ولكن ضمن سياق Procedural Logic

هذه معلومات قيّمة وقد استفدت منها كثيراً، ووجدت أسماء لأشياء لم أكن اعرف اسمها، مثل الـ procedural logic. وهي عادة يأتي بها الشخص القادم من لغات البرمجة اﻹجرائية.

كذلك قلة التداخل coupling

جواب شافي و كافي، ربما أستطيع إضافة بضع نقاط..

  • Open Close Principle: بحيث تصبح الكلاسات، الموديولز، الدوال وغيرها قابلة للتغيير، التطوير، المراجعة، سهلة أثناء الـ (Unit Tests) ليس فقط بالإعتماد على الـ Interfaces لكن كذلك باستغلال أنماط التصميم المختلفة.

  • Separation of concerns: تحدثت عنها بقولك: "جعل الدوال والكلاسات لديك مسؤولة عن شيء واحد فقط".. ولا يتعلق الأمر بالدوال و الكلاسات فقط، لكن يمكن تعميمه على طبقات و أجزاء التصميم ككل، بحيث تصبح "المعمارية؟" (Architecture) Multi Layered بحيث يتم تقسيم "النظام" لعدة "طبقات" (Layers) مكلفة كل واحدة منها بجزء محدد من العمل. كمثال بسيط: تطبيق ويب يجب أن يحتوي على Data Access Layer مكلفة خصيصا للتعامل مع data source كقاعدة البيانات مثلا، من الربط بها إلى التعامل مع الـ Exceptions الخاصة بها أو حتى تهيئة الـ ORM في حالة استعماله، كل هذا يكون عاما بعيدا عن خصوصيات الـ Business Logic التي تحيلنا لطبقة أخرى تتوفر على الكلاسات و الـ Logic الخاص ببرنامجنا. هنا يمكن أيضا في بعض الإستثناءات تفريق الـ Business Logic عن الـ Enities المكونة للنظام ككل.

بعد الـ Layers التي تم ذكرها، يمكن إضافة Layer خاص بالـ Presentation أو كل ما يشكل صلة وصل بمستعملي النظام (End User)، كالـ End Services أو بنية MVC خارجية، حيث الكونترولر في هذه الحالة يرتبط بالـ Business Logic لتوفير الداتا للـ vues و غيرها دون أدنى تدخل في الـ Logic.

الكلمة المفتاح هنا هي الـ Dependency Injection.

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

لقد حاولت تصميم إطار عمل يكون عام وشمولي بحيث يأخذ معظم هذه النقاط بعين الاعتبار

سبق وشرحت فكرته في الموضوع التالي :