تصميم الخوارزميات الحرجة: التنفيذ

  1. التصميم
  2. التنفيذ
  3. دمج


عندما كنت قد بدأت للتو مسيرتي في مجال التطوير المهني ، لم أفهم سبب الحاجة إلى مصدر مفتوح. لم أفهم المشاريع الجانبية أيضًا ، في هذا الشأن. بعد كل شيء ، لماذا تعطي عملاً قيماً مجانًا؟ على مر السنين ، من خلال العمل على مشاريع مفتوحة المصدر ، بالإضافة إلى العمل مع Apex.AI و ROS 2 و Autoware.Auto ، لقد توصلت إلى بعض الفهم للمصادر المفتوحة.



المهندسون يحبون الإبداع. يريد الناس الاعتراف والامتنان.



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



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



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



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



تخطيط مشاريع مفتوحة المصدر



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



يمكن لمجموعة المهارات الخاصة هذه أن تقودنا المهندسين إلى الإرهاق إلى حد ما.



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



هنا يأتي دور السحر الأسود لإدارة المشاريع.



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



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



لذا ماذا نفعل بعد ذلك؟



حسنًا ، يمكننا نحن المطورين جعل أيدينا متسخة وقضاء بعض الوقت في التخطيط للمستقبل.



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



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



مع تطور مشروعك ، ستكون مهمتك هي أخذ التذاكر بالترتيب حسب الأولوية وإكمال المهام المسندة إليها.



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



تطوير مفتوح



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



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



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



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



  1. الاختبارات (أو الأفضل من ذلك ، التطوير القائم على الاختبار)
  2. تحليل ثابت
  3. التكامل المستمر (CI / CD)
  4. مراجعة التعليمات البرمجية


سأعطيك أيضًا عددًا من المبادئ التي ألتزم بها عند كتابة التعليمات البرمجية مباشرة:



  1. جاف
  2. الاستخدام الكامل للغة والمكتبات
  3. يجب أن يكون الرمز مقروءًا وواضحًا.


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



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



اختبارات



لنتحدث عن الاختبار.



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



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



الآن لدي علاقة طبيعية مع الاختبار. إنه جزء لا يتجزأ من سير العمل الخاص بي ، بغض النظر عن التطبيق الذي أعمل عليه.



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



لقد تحدثت لفترة وجيزة عن التطوير القائم على الاختبار في النص السابق ، ولكن إليك وصفًا آخر للعملية:



  1. وضع مواصفات (حالات الاستخدام ، والمتطلبات ، وما إلى ذلك).
  2. تنفيذ API / الهندسة المعمارية
  3. كتابة الاختبارات على أساس API ومواصفات التصميم ؛ يجب أن يفشلوا.
  4. تنفيذ المنطق ؛ يجب أن تجتاز الاختبارات


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



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



ثم ننتقل إلى كتابة الاختبارات. هناك عدة أسباب لفوائد كتابة الاختبارات قبل التنفيذ ، وأعتقد أنها كلها مهمة:



  1. يجب كتابة الاختبارات ككائنات ذات أولوية أولى ، وليس كوظائف إضافية.
  2. , – .
  3. API , .
  4. , , , , .


بشكل عام ، أعتقد أن فوائد التطوير المدفوع باختبار هائلة ، ومرة ​​أخرى أوصي بشدة الجميع بتجربتها على الأقل.



لنعد إلى Autoware.Auto. قام يونس ، بينما لم يلتزم بأساليب التطوير القائمة على الاختبار ، بكتابة اختبارات لكل طلب دمج أثناء تطوير NDT. في الوقت نفسه ، كان حجم رمز الاختبار مساويًا (وأحيانًا تجاوز) حجم رمز التنفيذ ، وهذا أمر جيد. بالمقارنة ، SQLite ، التي ربما تكون المعيار للاختبار (ليس فقط وفقًا لمعايير المشاريع مفتوحة المصدر) ، لديها كود اختبار أكثر بـ 662 مرة من رمز التنفيذ... في Autoware ، نحن لسنا في هذه المرحلة تمامًا حتى الآن ، ولكن إذا نظرت إلى سجل طلبات الدمج المتعلقة بـ NDT ، فستلاحظ أن حجم رمز الاختبار يزحف ببطء حتى يصل إلى تغطية 90٪ (على الرغم من أنه انخفض منذ ذلك الحين بسبب تصاميم أخرى ورمز خارجي).



وهذا رائع.



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



أنا رفيق جيد.



تحليل ثابت



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



هذه "الاختبارات" مؤلمة إلى حد ما ومرهقة للعمل معها. بعد كل شيء ، التحقق ، التحقق من صحة علامات التبويب / مسافات في المحاذاة؟ لا شكرا.



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



حسنًا ، يمكننا - باستخدام أدوات التحليل الثابتة.



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



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



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



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



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



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



CI / CD



بقدر ما أحب الاختبارات الصارمة وتحليل الشفرة الثابتة / الديناميكية ، فإن جميع الاختبارات والشيكات لا قيمة لها إذا لم يتم تشغيلها. يمكن لـ CI مواجهة هذه التحديات بأقل قدر من النفقات العامة.



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



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



لكن CI يمكن أن تفعل الكثير لك.



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



بالعودة إلى البيان الأصلي ، فإن وجود خط أنابيب CI / CD (الذي نستخدمه في Autoware.Auto ) في مشروعك مفتوح المصدر سيساعد على ركوب التطوير الذي لا يمكن إدارته. لن يتمكن الرمز من الدخول إلى المشروع إذا لم يقم ببناء أو اجتياز الاختبارات. إذا كنت تلتزم بنظام اختبار صارم ، فيمكنك دائمًا التأكد من أن الرمز يعمل.



في Autoware.Auto ، CI:



  1. يجمع الرمز
  2. تشغيل الاختبارات (الأسلوب ، فحوصات اللنتر ، الاختبارات الوظيفية).
  3. يقيس تغطية الاختبار
  4. يتحقق من أن الرمز موثق




في المقابل ، CI جمعت على عجل في مشروع mpc:



  1. يجمع الرمز
  2. يقوم بإجراء مسح (تحليل ثابت Clang)
  3. تشغيل الاختبارات (ولكن لا يوقف CI إذا فشلت الاختبارات).


يمكن لخط أنابيب CI الذي وضعه مهندس DevOps ذو الخبرة (مثل JP Samper أو Hao Peng !) أن يفعل أكثر من ذلك بكثير. لذا نعتز به مهندسي DevOps. إنهم يجعلون حياتنا (كمطورين) أسهل بكثير.



مراجعة التعليمات البرمجية



المقاييس والتحليلات و CI رائعة. يمكنك إجراء الاختبارات وتحليل كل شيء والتأكد من إجراء هذه الاختبارات باستخدام CI ، أليس كذلك؟



للاسف لا.



مرة أخرى ، كل الاختبارات في العالم لا قيمة لها إذا كانت سيئة. إذن كيف تتأكد من أن اختباراتك جيدة؟



لسوء الحظ ، ليس لدي إجابات سحرية. في الواقع ، سأعود إلى التقنية الهندسية القديمة ، مراجعة الأقران. على وجه الخصوص ، لمراجعة التعليمات البرمجية.



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



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



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



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



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



ومع ذلك ، أعتقد أن مراجعات الشفرة يمكن أن تكون ممتعة وغير مؤلمة إذا تذكر كل من المراجع والمراجع النظير ما يلي:



  1. أنت لست رمزك.
  2. أنت تتحدث إلى شخص آخر.
  3. كن مهذبا
  4. الجميع يعمل من أجل نفس الهدف ؛ مراجعة الكود لا تمثل أي منافسة (على الرغم من أنها تحدث أحيانًا في البرمجة )


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



جاف



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



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



هناك بعض المفاهيم التي ساعدتني على تحسين التعليمات البرمجية الخاصة بي بشكل كبير. كان أحد هذه المفاهيم هو القدرة على تذكر النية ، والدلالات ، وإمكانية القراءة ، والتي سأتحدث عنها بعد ذلك بقليل. آخر هو فهم OOP و فصل الاهتمامات . الفكرة المهمة الأخيرة هي DRY ( لا تكرر نفسك ) أو مبدأ "لا تكرر نفسك".



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



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



لكن DRY تذهب إلى أبعد من التحقق من أنه يجب نقل بعض التعليمات البرمجية إلى دالة. يمكن أن يكون هذا المفهوم أيضًا بمثابة أساس لبعض القرارات المعمارية.



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



كان هذا مؤشراً جيداً على وجوب فصل التصاميم والوظائف العامة إلى فصل منفصل . كان العائد ذو شقين: وحدة تحكم mpc تركز بنسبة 100 ٪ على الكود المتعلق بـ mpc ، ومعالوحدة النمطية المرتبطة بها ليست سوى قالب التكوين. وبعبارة أخرى ، بسبب التجريد المعماري ، لا يتعين علي إعادة كتابة كل شيء عند العمل مع وحدة تحكم مختلفة.



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



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



الاستخدام الكامل للغة والمكتبة



DRY ، في رأيي ، هو مفهوم مهم ومنتشر لدرجة أن هذه النقطة هي في الواقع مجرد استمرار لمحادثة DRY.



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



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



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



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



رمز مقروء



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



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



  1. حاول أن تجعل فصولك الدراسية واضحة ومركزة:

    • قلل التمزق
    • ()



      • const, noexcept? ? (, )




    • , (, , ).
    • (, )
    • .
  2. -



    • «», , .
    • (, ).
    • ( ) ().
  3. ? ()



    • , ().
    • , , , (, ).


مورد آخر رائع يعالج هذا النوع من المشاكل هو إرشادات ISO C ++ الأساسية .



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



النظر إلى الخلف



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



بشكل عام ، استفدنا بشكل كبير من الأدوات والممارسات التي ذكرتها ، لكننا لم نكن مثاليين.



لذا ، على سبيل المثال ، عند العمل على NDT ، لم نتبع التعابير الخاصة بالتنمية التي تعتمد على الاختبار (على الرغم من أننا قد اختبرنا كل شيء تمامًا!). في المقابل ، اتبعت تقنيات التطوير التي تعتمد على الاختبار على MPC ، لكن هذا المشروع لم يستفد من CI الأكثر قوة المضمنة في Autoware.Auto. علاوة على ذلك ، لم يكن مشروع MPC عامًا وبالتالي لم يتلق فوائد مراجعة الكود.



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



ليس لدي ما أقوله عن التطوير المتزامن لخوارزميتين - لقد عملنا بأفضل ما لدينا من قدرات ، مع الالتزام بالمبادئ التي أشرت إليها أعلاه.



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



التحرك إلى الأمام



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



سأغطي هذا في المنشور الثالث والأخير من هذه السلسلة.



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



في الواقع ، كان قادرًا على تشغيل (تجاوز عدم التوافق QoS وخيارات الإعداد) تقريبًا خارج الصندوق .



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



ليس سيئًا للمنتجات المصممة ليراها الجميع.



اشترك في القنوات:

TeslaHackers — Tesla-, Tesla

@AutomotiveRu — ,







صورة



- automotive . 2500 , 650 .



, , . ( 30, ), -, -, - (DSP-) .



, . , , , . , automotive. , , .


:






All Articles