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

نرم‌افزار · · زمان مطالعه: ۵ دقیقه

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

بازبینی کد (Code Review) در بسیاری از تیم‌های نرم‌افزاری به آیینی تشریفاتی تبدیل شده است: کسی چند خط را از نظر می‌گذراند، یک تأیید کوتاه می‌گذارد و کار جلو می‌رود. اما در تیم‌هایی که این گام را جدی می‌گیرند، همین فرایند کوچک تعیین می‌کند که نرم‌افزار دو سال بعد قابل نگهداری باشد یا به باتلاق تغییرهای پرهزینه تبدیل شود. زاویهٔ این نوشته فنی نیست، سازمانی است: می‌خواهیم بازبینی کد را نه یک مرحلهٔ تشریفاتی در گردش‌کار، بلکه آینهٔ فرهنگ مهندسی تیم ببینیم.

بازبینی کد چه چیزی را حل می‌کند و چه چیزی را نه

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

در مقابل، بازبینی کد ابزار درستی برای کارهایی نیست که ماشین بهتر انجام می‌دهد. قالب‌بندی، نام‌گذاری‌های پیش‌پاافتاده، ترتیب وارد‌کردن کتابخانه‌ها و خطاهای نحوی، کار ابزارهای قالب‌بند و تحلیل ایستا (Static Analysis) است. اگر وقت بازبین صرف این‌ها شود، انرژی او برای پرسش‌های مهم—«این تغییر مسئولیت درستی دارد؟» یا «اگر این فراخوانی شکست بخورد چه می‌شود؟»—تمام می‌شود. بازبینی مؤثر یعنی جابه‌جا کردن توجه از چیزی که قابل اندازه‌گیری است به چیزی که اهمیت دارد.

الگوهایی که بازبینی را به گلوگاه تبدیل می‌کنند

  • تغییرهای غول‌آسا: درخواست ادغام (Pull Request) که صدها خط را در خود جا داده، عملاً بازبینی‌پذیر نیست. بازبین یا سطحی از آن می‌گذرد یا ساعت‌ها وقت می‌گذارد؛ در هر دو حالت، خطاهای ظریف از دست می‌روند.
  • بازبینی به‌جای تأیید شخصی: وقتی تنها یک نفر حق تأیید دارد، بازبینی از یک گفت‌وگوی فنی به یک صف انتظار تبدیل می‌شود و آن یک نفر به گلوگاه تیم بدل می‌شود.
  • تأخیر طولانی: اگر پاسخ بازبین یک روز کاری طول بکشد، نویسنده ذهنش را از آن تغییر برداشته است. بازخورد دیرهنگام گران‌تر از بازخورد ناقصِ سریع تمام می‌شود.
  • نبود معیار روشن: تیمی که نمی‌داند «کافی خوب» چه معنایی دارد، یا بی‌نهایت سخت‌گیر می‌شود یا بی‌نهایت بی‌خیال؛ هر دو حالت فرهنگ را فرسوده می‌کند.

راه‌حل این الگوها فنی است، اما پیامدشان فرهنگی: کوچک کردن تغییرها، محدود نکردن حق تأیید به یک نفر، و تعریف صریح تعریفِ «آمادهٔ ادغام».

سه لایه‌ای که باید ببینیم

لایهٔ یک: چیزی که ابزار می‌بیند

اگر خط لولهٔ ساخت (Build Pipeline) شما قالب‌بندی و تحلیل ایستا را اجرا می‌کند، دیگر هیچ‌کس نباید دربارهٔ آن‌ها نظر بدهد. این لایه باید کاملاً خودکار باشد تا لایه‌های بعدی جا باز کنند.

لایهٔ دو: طراحی و مسئولیت‌ها

پرسش اصلی این است: این تغییر چه چیزی را به سیستم اضافه می‌کند و آیا جای درستی نشسته است؟ آیا تابعی که نوشته شده دو مسئولیت بی‌ربط را با هم جمع نکرده؟ آیا کد تکراری‌ای ساخته شده که فردا باید در دو جا اصلاح شود؟ این‌ها پرسش‌هایی هستند که ابزار پاسخشان را ندارد.

لایهٔ سه: مرزهای اعتماد و مسیرهای خطا

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

فرهنگ: بازخورد روی کد، نه روی نویسنده

تفاوت تیمی که بازبینی را جدی می‌گیرد با تیمی که از آن می‌ترسد، در یک چیز است: جهت‌گیری بازخورد. جملهٔ «این تابع مسئولیت‌های زیادی دارد» دربارهٔ کد است؛ جملهٔ «تو همیشه کد را شلوغ می‌نویسی» دربارهٔ شخص است و فقط دفاع ایجاد می‌کند.

سه عادت کوچک این تفاوت را می‌سازد: پرسیدن «چرا» پیش از حکم دادن، جداکردن نظر شخصی از ترجیح تیمی («سلیقهٔ من این است» در برابر «قرارداد ما این است»)، و پذیرفتن اینکه مالکیت جمعی کد یعنی هیچ‌کس مالک انحصاری یک ماژول نیست. در تیمی که این عادت‌ها جا افتاده، بازبین هم می‌تواند اشتباه خود را بپذیرد و نویسنده هم از تغییر بزرگ نمی‌ترسد.

تقسیم کار میان انسان، خط لوله و دستیارها

یک تقسیم کار ساده کمک می‌کند بازبینی سبک بماند: هر چیزی که با قاعده قابل تشخیص است به خط لولهٔ یکپارچه‌سازی مداوم (Continuous Integration) سپرده شود؛ هر چیزی که به قضاوت دربارهٔ طرح و ریسک نیاز دارد به انسان؛ و هر چیزی که به توضیح و مستندسازی نیاز دارد به خود نویسندهٔ تغییر.

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

یک چک‌لیست سبک برای شروع

  1. اندازه: آیا تغییر در یک نشست قابل بازبینی است؟ اگر نه، همان‌جا درخواست تقسیم بدهید.
  2. توضیح: آیا نویسنده در چند خط گفته چه چیزی و چرا تغییر کرده است؟
  3. طرح: آیا مسئولیت‌ها سر جای خود هستند و کد تکراری تازه‌ای ساخته نشده است؟
  4. مسیرهای خطا: اگر این فراخوانی‌ها شکست بخورند، سیستم چه رفتاری نشان می‌دهد؟
  5. تست: آیا رفتار جدید آزمون دارد و آزمون‌ها واقعاً چیزی را بررسی می‌کنند؟
  6. مرز اعتماد: ورودی بیرونی کجا اعتبارسنجی می‌شود و آیا دادهٔ حساسی بیرون می‌رود؟
  7. خواندن برای فردا: آیا کسی که شش ماه بعد این کد را می‌خواند، می‌تواند قصد آن را بفهمد؟

جمع‌بندی

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

← بازگشت به همه مقالات