فصل دوم: بازبینی کد – فرآیند و اهمیت 🖥️

هدف اصلی بازبینی کد، بهبود کیفیت کلی کد است. کیفیت کد به ویژه در پروژه‌های تیمی یا پروژه‌هایی که توسط دیگران (مثل توسعه‌دهندگان متن‌باز یا مشتریان از طریق قراردادهای escrow) قابل دسترسی است، اهمیت زیادی دارد.

اگر هر توسعه‌دهنده آزاد باشد به سبک دلخواه خود کدنویسی کند، کد به صورت مجموعه‌ای از سبک‌های متفاوت و در نهایت یک کد نامنظم و پیچیده تبدیل می‌شود. به همین دلیل داشتن سیاست استانداردهای کدنویسی و فرآیند بازبینی کد ضروری است.

در بازبینی کد، همکاران کد یکدیگر را بررسی می‌کنند و به موارد زیر توجه دارند:


موضوعات این فصل

  1. آماده‌سازی کد برای بازبینی
  2. رهبری یک بازبینی کد
  3. دانستن اینکه چه چیزی باید بررسی شود
  4. دانستن زمان مناسب برای ارسال کد به بازبینی
  5. ارائه و پاسخ‌دهی به بازخوردهای بازبینی

توجه:


اهداف یادگیری


فرآیند بازبینی کد

۱. مطمئن شوید که کد کامپایل می‌شود و نیازمندی‌ها را برآورده می‌کند.
۲. اطمینان حاصل کنید که تمام Unit Test و End-to-End Test ها با موفقیت اجرا می‌شوند.
۳. کد را در شاخه کاری فعلی (working branch) چک این کنید.
4. یک Pull Request صادر کنید.
5. Peer Reviewer کد شما را بررسی و بازخورد ارائه می‌دهد.
6. اگر کد تایید شد، می‌توانید شاخه کاری خود را به شاخه اصلی (main trunk) ادغام کنید.
7. اگر بازبینی رد شد، باید مشکلات گزارش شده را برطرف کنید و دوباره بررسی را درخواست دهید.

نمودار فرآیند بازبینی کد توسط همتایان (Peer Code Review) این روند را به صورت تصویری نشان می‌دهد.


Conventions-UsedThis-Book

آماده‌سازی کد برای بازبینی 🛠️

آماده‌سازی کد برای بازبینی ممکن است گاهی کار زمان‌بر و خسته‌کننده‌ای باشد، اما کیفیت کلی کد را بهبود می‌بخشد و آن را خوانا و قابل نگهداری می‌کند. این یک عمل ضروری است که تیم‌ها باید به عنوان روند استاندارد کدنویسی انجام دهند.

نکات مهم هنگام آماده‌سازی کد برای بازبینی:

  1. همیشه بازبینی کد را در ذهن داشته باشید:
    از ابتدای برنامه‌نویسی به بازبینی کد فکر کنید. کد خود را کوچک نگه دارید و اگر ممکن است، محدود به یک ویژگی (feature) باشید.

  2. اطمینان از گذراندن تمام تست‌ها حتی اگر کد کامپایل شود:
    اگر کد شما کامپایل می‌شود اما تست‌ها رد شده‌اند، فوراً دلیل آن را برطرف کنید. تمام Unit Test و End-to-End Test باید موفقیت‌آمیز باشند تا از مشکلات بعدی در محیط تولید جلوگیری شود.

  3. به YAGNI توجه کنید:
    تنها کدی را اضافه کنید که برای برآورده کردن نیازمندی یا ویژگی مورد نظر ضروری است. اگر نیاز نیست، کدنویسی نکنید.

  4. بررسی کدهای تکراری:
    اگر کد شما باید شیءگرا، DRY و SOLID باشد، کد خود را بررسی کنید تا از وجود کد تکراری یا رویه‌ای مطمئن شوید. در صورت وجود، آن را بازسازی (refactor) کنید.

  5. استفاده از ابزارهای تحلیل استاتیک:
    این ابزارها با تنظیمات استانداردهای شرکت، کد شما را بررسی و مشکلات را مشخص می‌کنند. هشدارها را نادیده نگیرید، زیرا ممکن است بعداً مشکل‌ساز شوند.

  6. اطمینان از رضایت از کد قبل از چک این:
    فقط وقتی مطمئن شدید که کد:

    • نیازمندی‌های تجاری را برآورده می‌کند
    • استانداردهای کدنویسی رعایت شده‌اند
    • تمام تست‌ها موفقیت‌آمیز هستند
      چک این کنید.
      اگر بخشی از Continuous Integration (CI) باشد و کد باعث شکست build شود، باید مشکلات را برطرف کنید و دوباره تلاش کنید.

رهبری بازبینی کد 👨‍💻

هنگام رهبری یک بازبینی کد، حضور افراد مناسب اهمیت دارد. حضور برنامه‌نویسان مسئول ارسال کد ضروری است، مگر اینکه از راه دور کار کنند. در آن صورت، بازبین کد pull request را بررسی کرده و:

مهارت‌ها و دانش مورد نیاز رهبر بازبینی کد:

  1. اقتدار فنی: رهبر باید با استانداردهای کدنویسی و متدولوژی‌های توسعه نرم‌افزار آشنا باشد و درک کلی از نرم‌افزار تحت بررسی داشته باشد.
  2. مهارت‌های نرم: باید فردی گرم و تشویق‌کننده باشد و بتواند بازخورد سازنده ارائه دهد تا تعارضی ایجاد نشود.
  3. عدم انتقاد بیش از حد: باید بتواند انتقادات خود را به شکل سازنده و روشن بیان کند و کد را به صورت عینی بررسی نماید.

فرآیند بازبینی کد با Pull Request

  1. برنامه‌نویس کد را در سیستم کنترل نسخه چک این می‌کند و Pull Request صادر می‌کند.

  2. Peer Reviewer کد را بررسی و بازخورد ارائه می‌دهد:

    • مشکلات را مشخص می‌کند
    • در صورت نیاز، Pull Request را رد می‌کند
    • بازخورد مثبت در صورت موفقیت ارائه می‌دهد و Pull Request را Merge می‌کند
  3. برنامه‌نویس باید تمام نظرات بازبین را اعمال کند و در صورت نیاز، کد را دوباره ارسال کند.

نکته: بازبینی‌های کوتاه و تعداد خطوط محدود، مؤثرتر و آسان‌تر برای مدیریت هستند.


صدور Pull Request در گیت‌هاب 🔄

وقتی کدنویسی شما کامل شد و از کیفیت کد و موفقیت‌آمیز بودن Build اطمینان پیدا کردید، می‌توانید تغییرات خود را در مخزن Source Control Push یا Check-in کنید، بسته به سیستم کنترل نسخه‌ای که استفاده می‌کنید.

پس از ارسال کد، می‌توانید Pull Request صادر کنید. با ایجاد Pull Request:

به عبارت دیگر، Push کردن کد و صدور Pull Request آغازگر فرآیند بازبینی کد همتا (Peer Code Review) است.


مراحل صدور Pull Request

  1. پس از Check-in یا Push کد، به تب Pull Requests در مخزن خود بروید.
  2. روی دکمه New Pull Request کلیک کنید.
  3. Pull Request شما در صف انتظار قرار می‌گیرد تا بازبین‌های مربوطه آن را بررسی کنند.

این کار، فرآیند رسمی بازبینی کد را شروع می‌کند و به تیم کمک می‌کند کد با کیفیت بالا و استاندارد را تحویل دهد.

فرآیند درخواست و انجام Pull Request در GitHub 📝

مراحل زیر نحوه ایجاد و ارسال یک Pull Request در GitHub را نشان می‌دهد:

  1. رفتن به تب Pull Requests
    در صفحه پروژه GitHub خود، روی تب Pull Requests کلیک کنید.

Conventions-UsedThis-Book

  1. ایجاد Pull Request جدید
    روی دکمه New Pull Request کلیک کنید. این کار صفحه Comparing changes را نمایش می‌دهد تا تغییرات خود را مرور کنید.

Conventions-UsedThis-Book

  1. شروع Pull Request
    اگر از تغییرات راضی بودید، روی دکمه Create pull request کلیک کنید. این صفحه Open a pull request را نمایش می‌دهد.

Conventions-UsedThis-Book

  1. افزودن توضیحات و جزئیات

    • در بخش توضیحات، کامنتی کوتاه و مفید بنویسید که تغییرات ایجاد شده را مشخص کند.
    • در صورت نیاز، فیلدهای Reviewers، Assignees، Labels، Projects و Milestones را تنظیم کنید.
    • وقتی آماده بودید، دوباره روی Create pull request کلیک کنید تا Pull Request ایجاد شود.

اکنون کد شما آماده بررسی توسط همتایان تیم است و فرآیند Peer Code Review آغاز می‌شود.

پاسخ به Pull Request در GitHub 🔄

هنگامی که شما به عنوان بررسی‌کننده (Reviewer) یک Pull Request را بررسی می‌کنید، مراحل زیر را دنبال کنید:

  1. کپی کردن کد برای بررسی
    ابتدا یک نسخه از کد تحت بررسی را Clone کنید تا بتوانید محلی تغییرات را بررسی کنید.

  2. بررسی کامنت‌ها و تغییرات
    کامنت‌ها و تغییراتی که نویسنده Pull Request ایجاد کرده است را مرور کنید.

  3. بررسی تداخل‌ها و وضعیت کد

    • مطمئن شوید که با شاخه پایه (Base branch) تداخلی وجود ندارد. اگر تداخل بود، Pull Request را رد کرده و توضیحات لازم را بدهید.
    • کد را بررسی کنید تا بدون خطا Build شود و هیچ هشدار کامپایل نداشته باشد.
    • مراقب Code Smells و باگ‌های احتمالی باشید.
    • بررسی کنید که تمام تست‌ها اجرا می‌شوند، صحیح هستند و پوشش مناسبی برای ویژگی مورد نظر ارائه می‌دهند.
    • اگر مشکلی بود، Pull Request را رد کنید و کامنت مناسب اضافه کنید.

Conventions-UsedThis-Book

  1. ادغام Pull Request
    وقتی از کیفیت کد رضایت داشتید:

    • کامنت‌های لازم را اضافه کنید.
    • روی دکمه Merge pull request کلیک کنید.
    • سپس برای تأیید، روی Confirm merge کلیک کنید.

Conventions-UsedThis-Book

  1. حذف شاخه پس از ادغام
    پس از ادغام و بسته شدن Pull Request، شاخه مربوطه را می‌توان با کلیک روی Delete branch حذف کرد.

Conventions-UsedThis-Book

با انجام این مراحل، شما فرآیند بررسی و پاسخ به Pull Request را تکمیل کرده و مطمئن می‌شوید که کد با کیفیت مناسب وارد شاخه اصلی پروژه می‌شود.

تأثیر بازخورد بر دریافت‌کنندگان بازبینی 📝

هنگام انجام کد ریویو (Code Review) روی کد همکار خود، باید این نکته را نیز در نظر بگیرید که بازخورد می‌تواند مثبت یا منفی باشد.

بازخورد منفی معمولاً جزئیات مشخصی از مشکل ارائه نمی‌دهد. در این حالت، مرورگر (Reviewer) روی شخص دریافت‌کننده بازخورد (Reviewee) تمرکز می‌کند نه روی مشکل. پیشنهادهایی برای بهبود کد به دریافت‌کننده ارائه نمی‌شود و هدف بازخورد مرورگر، آسیب رساندن به دریافت‌کننده است. ⚠️

بازخورد منفی که توسط دریافت‌کننده دریافت می‌شود، باعث رنجش و ناراحتی او می‌شود. این امر تأثیر منفی دارد و ممکن است باعث شود فرد شروع به شک و تردید در توانایی‌های خود کند. در نتیجه، انگیزه در دریافت‌کننده کاهش می‌یابد و این می‌تواند تیم را نیز تحت تأثیر منفی قرار دهد، زیرا کارها به موقع انجام نمی‌شوند یا کیفیت لازم را ندارند.

احساسات منفی بین مرورگر و دریافت‌کننده، توسط تیم نیز حس می‌شود و ممکن است جو خفقان‌آور و منفی بر کل تیم حاکم شود. این وضعیت می‌تواند باعث شود سایر همکاران نیز بی‌انگیزه شوند و در نهایت پروژه زمانی و مالی آسیب ببیند. ⏳💸

در نهایت، ممکن است دریافت‌کننده به جایی برسد که از وضعیت خسته شود و برای فرار از آن، محل کار جدیدی پیدا کند. در این صورت، پروژه دچار کاهش بهره‌وری و هزینه‌های اضافی خواهد شد، زیرا زمان و پول باید برای پیدا کردن جایگزین صرف شود.

هر فردی که برای جایگزینی انتخاب شود، باید با سیستم، رویه‌ها و دستورالعمل‌های کاری آموزش داده شود.

📉 نمودار زیر نشان‌دهنده بازخورد منفی مرورگر نسبت به دریافت‌کننده است:

Conventions-UsedThis-Book

برعکس، بازخورد مثبت مرورگر به دریافت‌کننده بازخورد تأثیر معکوس دارد 🌟

وقتی مرورگر بازخورد مثبت ارائه می‌دهد، تمرکز او روی مشکل است و نه روی شخص. در این حالت، مرورگر توضیح می‌دهد که چرا کدی که ارسال شده خوب نیست و مشکلات احتمالی آن چه هستند. سپس، راهکارهایی برای بهبود کد به دریافت‌کننده پیشنهاد می‌دهد. هدف بازخورد مرورگر، فقط بهبود کیفیت کد ارسال شده توسط دریافت‌کننده است. ✅

هنگامی که دریافت‌کننده بازخورد مثبت (سازنده) را دریافت می‌کند، به شکل مثبت پاسخ می‌دهد. او نظرات مرورگر را بررسی کرده و به شکل مناسب واکنش نشان می‌دهد: پاسخ به سوالات، پرسیدن سوالات مرتبط، و سپس به‌روزرسانی کد بر اساس بازخورد مرورگر. کد اصلاح‌شده دوباره برای بررسی و پذیرش ارسال می‌شود.

این فرآیند تأثیر مثبت بر تیم دارد، زیرا جو کلی تیم مثبت باقی می‌ماند و کارها به موقع و با کیفیت مورد انتظار انجام می‌شوند.

📈 نمودار زیر نشان‌دهنده نتایج بازخورد مثبت مرورگر بر دریافت‌کننده است:

Conventions-UsedThis-Book

نکته‌ای که باید به خاطر بسپارید: بازخورد شما می‌تواند سازنده یا مخرب باشد ⚖️

هدف شما به‌عنوان مرورگر، سازنده بودن بازخورد است و نه مخرب. یک تیم خوشحال، تیمی پربازده است؛ در حالی که یک تیم بی‌انگیزه، بهره‌وری ندارد و می‌تواند پروژه را به خطر بیندازد. بنابراین، همیشه سعی کنید با بازخورد مثبت تیم را خوشحال و انگیزه‌مند نگه دارید. 🌟

یک تکنیک برای ارائه انتقاد سازنده، روش ساندویچ بازخورد است. در این روش ابتدا نقاط مثبت را تحسین می‌کنید، سپس انتقاد سازنده ارائه می‌دهید و در پایان باز هم نقاط مثبت را برجسته می‌کنید. این روش مخصوصاً زمانی مفید است که اعضای تیم به هر نوع انتقاد واکنش منفی دارند. مهارت‌های نرم شما در تعامل با افراد به اندازه مهارت‌های نرم‌افزاری شما در ارائه کد باکیفیت اهمیت دارند. یادتان نرود! 💡

حال به بخش بعدی می‌رویم: چه چیزی را باید مرور کنیم؟ 🔍


دانستن اینکه چه چیزی را باید مرور کنیم 📝

هنگام مرور کد، جنبه‌های مختلفی باید مورد توجه قرار گیرد. مهم‌ترین نکته این است که تنها کدی که توسط برنامه‌نویس تغییر داده شده و برای بازبینی ارسال شده، مورد بررسی قرار گیرد. به همین دلیل، توصیه می‌شود که ارسال‌های کوچک و مکرر داشته باشید. مقادیر کم کد، بسیار راحت‌تر برای بررسی و ارائه نظر هستند.

بیایید جنبه‌های مختلفی که یک مرورگر کد باید برای یک بررسی کامل و دقیق ارزیابی کند را مرور کنیم:


دستورالعمل‌های کدنویسی شرکت و نیازمندی‌های کسب‌وکار 🏢

تمام کدی که مرور می‌شود باید با دستورالعمل‌های کدنویسی شرکت و نیازمندی‌های کسب‌وکار تطبیق داده شود. هر کد جدید باید با آخرین استانداردهای کدنویسی و بهترین شیوه‌های شرکت مطابقت داشته باشد.

انواع مختلفی از نیازمندی‌های کسب‌وکار وجود دارد، از جمله نیازهای کسب‌وکار و کاربر/ذینفع و نیازمندی‌های عملکردی و پیاده‌سازی. فرقی نمی‌کند که کد کدام نیازمندی را پوشش می‌دهد، باید به طور کامل بررسی شود تا از صحت آن اطمینان حاصل شود.

به‌عنوان مثال، اگر نیازمندی کاربر/ذینفع بیان می‌کند که «به‌عنوان کاربر، می‌خواهم یک حساب مشتری جدید اضافه کنم»، آیا کد تحت بررسی تمام شرایط این نیازمندی را برآورده می‌کند؟ اگر دستورالعمل‌های شرکت بیان می‌کند که تمام کدها باید تست واحد داشته باشند که جریان عادی و موارد استثنایی را آزمایش کند، آیا همه تست‌های لازم پیاده‌سازی شده‌اند؟ اگر پاسخ به هر یک از این سوالات نه باشد، کد باید با نظر مرورگر اصلاح شود، بازخورد داده شود و دوباره ارسال گردد.


قواعد نامگذاری ✍️

باید بررسی شود که قواعد نامگذاری برای سازه‌های مختلف کد مانند کلاس‌ها، اینترفیس‌ها، متغیرهای عضو، متغیرهای محلی، شمارنده‌ها و متدها رعایت شده باشد. هیچ کس نام‌های رمزگونه و سخت‌فهم را دوست ندارد، مخصوصاً وقتی پایگاه کد بزرگ باشد.

چند سوال که مرورگر باید از خود بپرسد:
1️⃣ آیا نام‌ها به اندازه کافی طولانی هستند تا قابل خواندن و فهمیدن توسط انسان باشند؟
2️⃣ آیا نام‌ها معنادار و مرتبط با هدف کد هستند، اما به اندازه کافی کوتاه هستند که بر برنامه‌نویسان دیگر آزاردهنده نباشند؟

به‌عنوان مرورگر، باید قادر باشید کد را بخوانید و درک کنید. اگر کد سخت خوانده و درک شود، باید قبل از ادغام، بازسازی و بازنویسی شود.

قالب‌بندی کد 🖋️

قالب‌بندی کد نقش بسیار مهمی در خوانا و قابل فهم کردن کد دارد. باید از namespaceها، آکولادها، و تورفتگی‌ها مطابق دستورالعمل‌ها استفاده شود و ابتدا و انتهای بلوک‌های کد به‌راحتی قابل تشخیص باشند.

در اینجا مجموعه‌ای از سوالاتی که مرورگر باید هنگام بازبینی مطرح کند آورده شده است:

1️⃣ آیا کد باید با استفاده از فاصله (Spaces) یا تب (Tabs) تورفتگی داشته باشد؟
2️⃣ آیا مقدار فضای خالی (White Space) به‌درستی استفاده شده است؟
3️⃣ آیا خطوطی از کد وجود دارند که خیلی طولانی هستند و باید به چند خط تقسیم شوند؟
4️⃣ وضعیت شکست خطوط (Line Breaks) چگونه است؟
5️⃣ مطابق با دستورالعمل سبک، آیا هر خط شامل تنها یک عبارت است؟ آیا هر خط تنها یک اعلان (Declaration) دارد؟
6️⃣ آیا خطوط ادامه به‌درستی با یک Tab Stop تورفتگی داده شده‌اند؟
7️⃣ آیا متدها با یک خط جدا شده‌اند؟
8️⃣ آیا چندین عبارت که یک Expression را تشکیل می‌دهند، با پرانتز از هم جدا شده‌اند؟
9️⃣ آیا کلاس‌ها و متدها پاک، کوچک، و فقط کار خود را انجام می‌دهند؟


تست‌کردن کد ✅

تست‌ها باید قابل فهم باشند و بخش مناسبی از حالات استفاده (Use Cases) را پوشش دهند. آن‌ها باید مسیرهای عادی اجرای کد و موارد استثنایی را شامل شوند. هنگام بررسی تست‌ها، مرورگر باید موارد زیر را بررسی کند:

1️⃣ آیا برنامه‌نویس تست برای تمام بخش‌های کد ارائه کرده است؟
2️⃣ آیا بخشی از کد وجود دارد که تست نشده باشد؟
3️⃣ آیا تمام تست‌ها کار می‌کنند؟
4️⃣ آیا هیچ یک از تست‌ها شکست می‌خورند؟
5️⃣ آیا مستندسازی کافی برای کد وجود دارد، از جمله کامنت‌ها، Documentation Comments، تست‌ها، و مستندات محصول؟
6️⃣ آیا چیزی در کد دیده می‌شود که با وجود اینکه کامپایل می‌شود و در حالت جداگانه کار می‌کند، می‌تواند هنگام ادغام باعث بروز خطا شود؟
7️⃣ آیا کد به‌خوبی مستندسازی شده تا نگهداری و پشتیبانی را آسان کند؟

بیایید ببینیم فرآیند چگونه پیش می‌رود: 🔄

Conventions-UsedThis-Book

کدهای تست‌نشده و مستندسازی 🧪📄

کدهایی که تست نشده‌اند ممکن است در حین تست یا حتی در محیط تولید، باعث بروز استثناهای غیرمنتظره شوند. اما به همان اندازه، تست‌های نادرست نیز می‌توانند خطرناک باشند. این موضوع می‌تواند باعث بروز باگ‌هایی شود که تشخیص آن‌ها دشوار است، مشتری را ناراحت کند و در آینده برای شما کار اضافی ایجاد کند.

باگ‌ها نوعی بدهی فنی (Technical Debt) محسوب می‌شوند و از دید کسب‌وکار، امری منفی تلقی می‌شوند. علاوه بر این، ممکن است شما کد را نوشته باشید، اما دیگران مجبور شوند آن را بخوانند و برای نگهداری و گسترش پروژه از آن استفاده کنند. بنابراین همیشه ایده خوبی است که مستنداتی برای همکارانتان ارائه دهید.

در مورد مشتری هم، چگونه می‌توانند بفهمند ویژگی‌های شما کجا هستند و چگونه از آن‌ها استفاده کنند؟ مستندات خوب و کاربرپسند ایده بسیار مناسبی است. به یاد داشته باشید که همه کاربران ممکن است از نظر فنی حرفه‌ای نباشند؛ بنابراین باید به کاربران کم‌تجربه نیز توجه کنید، بدون اینکه رفتار مستبدانه یا تحقیرآمیز داشته باشید.

اگر شما به‌عنوان مرجع فنی (Technical Authority) کد را بررسی می‌کنید، آیا Code Smell یا مشکلات بالقوه‌ای را شناسایی می‌کنید؟ در این صورت باید آن‌ها را علامت‌گذاری، کامنت‌گذاری و درخواست بازنگری (Pull Request) را رد کنید و از برنامه‌نویس بخواهید کد خود را دوباره ارسال کند.


بررسی استثناها و مدیریت خطا ⚠️

به‌عنوان مرورگر، باید اطمینان حاصل کنید که استثناها برای کنترل جریان برنامه استفاده نمی‌شوند و پیام‌های خطا معنادار و مفید برای توسعه‌دهندگان و مشتریان هستند.


دستورالعمل‌های معماری و الگوهای طراحی 🏗️

کد جدید باید بررسی شود تا با دستورالعمل‌های معماری پروژه مطابقت داشته باشد. کد باید از الگوهای برنامه‌نویسی مورد استفاده شرکت پیروی کند، مانند: SOLID, DRY, YAGNI, OOP. همچنین در صورت امکان، باید الگوهای طراحی (Design Patterns) مناسب را استفاده کند.

در اینجا الگوهای Gang-of-Four (GoF) مطرح می‌شوند. GoF شامل چهار نویسنده کتاب Design Patterns: Elements of Reusable Object-Oriented Software است: Erich Gamma, Richard Helm, Ralph Johnson, و John Vlissides.

امروزه این الگوهای طراحی در اکثر زبان‌های برنامه‌نویسی شیءگرا به‌طور گسترده استفاده می‌شوند. منبع بسیار خوب برای مطالعه: DoFactory .NET Design Patterns که هر الگوی GoF را با تعریف، نمودار کلاس UML، شرکت‌کنندگان، کد ساختاری و مثال واقعی توضیح داده است.

انواع الگوهای GoF:

کد باید به‌درستی سازمان‌دهی شده و در Namespace و Module مناسب قرار گیرد. همچنین بررسی شود که کد خیلی ساده یا بیش از حد پیچیده (Over-Engineered) نباشد.


عملکرد و امنیت ⚡🔒

موارد دیگری که باید در نظر گرفته شوند شامل عملکرد و امنیت است:

1️⃣ عملکرد کد چقدر خوب است؟
2️⃣ آیا گلوگاه‌ها (Bottlenecks) وجود دارد که باید رفع شوند؟
3️⃣ آیا کد به‌گونه‌ای نوشته شده که از حملات SQL Injection و Denial-of-Service محافظت کند؟
4️⃣ آیا داده‌ها اعتبارسنجی شده و فقط داده‌های معتبر در پایگاه ذخیره می‌شوند؟
5️⃣ آیا رابط کاربری، مستندات و پیام‌های خطا از نظر املایی بررسی شده‌اند؟
6️⃣ آیا اعداد جادویی (Magic Numbers) یا مقادیر Hard-Coded وجود دارد؟
7️⃣ آیا داده‌های پیکربندی درست هستند؟
8️⃣ آیا اطلاعات محرمانه (Secrets) به‌طور تصادفی چک شده‌اند؟

یک بررسی کامل کد باید تمام جنبه‌های ذکر شده و پارامترهای مرتبط با آن‌ها را شامل شود. اما قبل از آن، باید بدانیم چه زمانی مناسب است که یک بررسی کد انجام شود.

زمان مناسب برای ارسال کد جهت بازبینی ⏱️💻

بازبینی کد باید زمانی انجام شود که توسعه کد کامل شده باشد و قبل از آنکه برنامه‌نویس کد را به بخش QA تحویل دهد. قبل از اینکه هر کدی در Version Control چک شود، باید اطمینان حاصل شود که کد بدون خطا، هشدار یا پیام اطلاعاتی اجرا می‌شود. برای این کار می‌توانید اقدامات زیر را انجام دهید:

1️⃣ اجرای تحلیل استاتیک کد (Static Code Analysis) برای شناسایی مشکلات احتمالی. اگر خطا، هشدار یا پیام اطلاعاتی دریافت کردید، هر مورد را بررسی و اصلاح کنید. از آن‌ها چشم‌پوشی نکنید، زیرا ممکن است در آینده مشکلاتی ایجاد کنند. می‌توانید به صفحه Code Analysis در Properties پروژه Visual Studio 2019 دسترسی داشته باشید: روی پروژه راست‌کلیک کنید و مسیر Properties | Code Analysis را انتخاب کنید.

2️⃣ اطمینان از اینکه تمام تست‌ها با موفقیت اجرا می‌شوند و کد جدید شما به طور کامل توسط تست‌های مسیرهای عادی و استثنایی پوشش داده شده است تا صحت کد نسبت به مشخصات پروژه بررسی شود.

3️⃣ اگر در محل کار خود از فرآیند توسعه پیوسته (Continuous Development) استفاده می‌کنید که کد شما را در یک سیستم بزرگ‌تر ادغام می‌کند، باید اطمینان حاصل کنید که ادغام سیستم با موفقیت انجام شده و تمام تست‌ها بدون خطا اجرا می‌شوند. اگر خطایی مشاهده شد، باید قبل از ادامه کار آن را رفع کنید.

وقتی کد شما کامل، مستندسازی شده و تست‌ها با موفقیت اجرا شدند و ادغام سیستم بدون مشکل انجام شد، بهترین زمان برای انجام بازبینی کد توسط همتایان (Peer Code Review) است.

پس از تایید بازبینی کد همتا، کد شما می‌تواند به بخش QA منتقل شود.

📊 نمودار زیر چرخه حیات توسعه نرم‌افزار (SDLC) را از مرحله توسعه کد تا پایان عمر کد نشان می‌دهد:

Conventions-UsedThis-Book

فرآیند توسعه و بازبینی کد 🛠️📋

برنامه‌نویس نرم‌افزار را طبق مشخصات توسعه می‌دهد. سپس کد منبع را در مخزن Version Control ثبت کرده و یک Pull Request صادر می‌کند. این درخواست بررسی می‌شود:

اگر تست داخلی QA موفقیت‌آمیز باشد، کد وارد User Acceptance Testing (UAT) می‌شود:

هنگامی که نرم‌افزار در دست مشتری قرار می‌گیرد، اگر باگی مشاهده شود، گزارش باگ توسط مشتری ثبت می‌شود. توسعه‌دهندگان سپس رفع باگ‌های مشتری را انجام می‌دهند و فرآیند از نو آغاز می‌شود. زمانی که محصول به پایان عمر خود برسد، از سرویس خارج می‌شود.


ارائه و پاسخ به بازخورد بازبینی 🔄💬

باید به خاطر داشت که بازبینی کد با هدف بهبود کیفیت کلی کد و مطابق با دستورالعمل‌های شرکت انجام می‌شود. بنابراین، بازخورد باید سازنده باشد و نباید بهانه‌ای برای تحقیر یا شرمنده کردن همکار باشد. به همین ترتیب، بازخورد بازبین نباید شخصی گرفته شود و پاسخ‌ها باید متمرکز بر اقدامات مناسب و توضیحات فنی باشد.

📊 نمودار زیر فرآیند صدور Pull Request (PR)، انجام بازبینی کد، و پذیرش یا رد PR را نشان می‌دهد:

Conventions-UsedThis-Book

ارائه بازخورد به‌عنوان بازبین 👩‍💻📝

قلدری و آزار در محیط‌های کاری می‌تواند مشکل‌ساز باشد و محیط‌های برنامه‌نویسی نیز از آن مستثنی نیستند. هیچ‌کس برنامه‌نویس مغروری را دوست ندارد که فکر می‌کند همه‌چیز را می‌داند. بنابراین، بازبین باید مهارت‌های نرم (Soft Skills) خوبی داشته باشد و دیپلماتیک باشد. به خاطر داشته باشید که برخی افراد به‌راحتی آزرده می‌شوند و ممکن است نظرات را اشتباه برداشت کنند. بنابراین، بدانید که با چه کسی سر و کار دارید و احتمال واکنش او چگونه است؛ این به شما کمک می‌کند تا روش و کلمات خود را با دقت انتخاب کنید.

به‌عنوان بازبین کد همتایان (Peer Code Reviewer)، مسئول هستید که نیازمندی‌ها را درک کرده و اطمینان حاصل کنید که کد مطابق با آن نیازمندی‌هاست. بنابراین، به دنبال پاسخ به این سوالات باشید:

پس از اتمام بازبینی، سه نوع بازخورد برای انتخاب وجود دارد: مثبت، اختیاری و انتقادی:


پاسخ به بازخورد به‌عنوان بازبین شده 👨‍💻🔄

به‌عنوان برنامه‌نویس Reviewee، باید زمینه کد خود را به‌صورت مؤثر به بازبین توضیح دهید. با ایجاد Commit‌های کوچک می‌توانید به بازبین کمک کنید، زیرا حجم کوچک کد راحت‌تر بررسی و تحلیل می‌شود. هرچه کد بیشتر باشد، احتمال اینکه مشکلات دیده نشوند افزایش می‌یابد. در زمان انتظار برای بازبینی کد، نباید تغییرات بیشتری روی کد انجام دهید.

بازخورد دریافتی می‌تواند مثبت، اختیاری یا انتقادی باشد:

به محض دریافت بازخورد بازبین، اقدام کنید و در صورت نیاز با او بحث و تبادل نظر داشته باشید.


خلاصه 📚

در این فصل به اهمیت انجام بازبینی کد، آماده‌سازی کد برای بازبینی، پاسخ به نظرات بازبین، رهبری بازبینی کد و مواردی که باید هنگام بازبینی بررسی کرد پرداختیم. مشخص شد که در بازبینی کد همتا دو نقش وجود دارد:

  1. بازبین (Reviewer): کسی که بازبینی کد را انجام می‌دهد.
  2. برنامه‌نویس مورد بازبینی (Reviewee): کسی که کد او بررسی می‌شود.

همچنین دیدید که:

بازبینی کد همتایان ممکن است زمان‌بر و ناراحت‌کننده باشد، اما در بلندمدت به محصولی با کیفیت بالا، قابل نگهداری و گسترش آسان منجر می‌شود و استفاده مجدد از کد را افزایش می‌دهد.

در فصل بعدی، با نوشتن کلاس‌ها، اشیاء و ساختار داده‌های تمیز آشنا می‌شوید. خواهید دید چگونه می‌توان کلاس‌ها را سازماندهی کرد، مسئولیت‌ها را تک‌وظیفه‌ای نگه داشت، و کامنت‌گذاری برای تولید مستندات را انجام داد. سپس به Cohesion و Coupling، طراحی برای تغییر و قانون دمتر (Law of Demeter) پرداخته می‌شود، و در نهایت با اشیاء و ساختار داده‌های Immutable، پنهان‌سازی داده و ارائه متدها در اشیاء آشنا خواهید شد.


پرسش‌ها ❓

  1. دو نقش در بازبینی کد همتا چیست؟
  2. چه کسی افراد شرکت‌کننده در بازبینی کد همتا را مشخص می‌کند؟
  3. چگونه می‌توان قبل از درخواست بازبینی کد، زمان و انرژی بازبین را صرفه‌جویی کرد؟
  4. هنگام بازبینی کد باید به چه مواردی توجه کنید؟
  5. سه دسته بازخورد کدام‌اند؟

منابع بیشتر 📖