ترفندهای کار تیمی که هر توسعه‌دهنده‌‌ای باید بداند

خواندن در 9 دقیقه - آخرین بروزرسانی در - کپی آدرس
نگاره از اینجا به امانت گرفته شده است.

پیش‌گفتار

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


هر زمان مردم درباره code review صحبت می‌کنند به صورت پیش‌فرض به شخصی که code review را انجام می‌دهد توجه می‌کنند در صورتی که برنامه‌نویس نیز به همان اندازه اهمیت دارد.

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

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

قانون طلایی: به زمان خواننده اهمیت بدهید.

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

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

یک جلسه code review زمانی سازنده خواهد بود که هر دو طرف (خواننده و برنامه‌نویس) به یک دیگر اعتماد داشته باشند. زمانی که خواننده کد بداند شما (برنامه‌نویس) نظر او را محترم شمرده و آن را جدی می‌گیرید، توجه بیشتری به کد شما می‌کنه و در نتیجه کد بهتری تولید خواهد شد.

ترفندهای کار تیمی که هر توسعه‌دهنده‌‌ای باید بداند

  1. ابتدا کد را خودتان مطالعه کنید.
  2. لیست تغییرات را به دقت تنظیم کنید.
  3. موارد آسان را به صورت خودکار مدیریت کنید.
  4. دامنه تغییرات را کوچک نگه دارید.
  5. تغییرات کدی و غیر کدی را جدا کنید.
  6. یک تغییر بزرگ را به چند تغییر کوچک بشکنید.
  7. به انتقاد‌ها پاسخ دوستانه و سازنده دهید.
  8. زمانی که خواننده اشتباه می‌کند صبور باشید.
  9. پاسخ شفاف و مشخص دهید.
  10. زمان پاسخ را کوتاه نگه دارید.

1. ابتدا کد را خودتان مطالعه کنید.

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

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

برای بررسی تلاش کنید محیطی که تیم از آن برای بررسی استفاده می‌کند را برای خود بازسازی کنید؛ این کار باعث میشه دقت بیشتری داشته باشید و شاید مواردی رو ببینید که در محیط توسعه خودتون از چشم می‌افتاد.

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

2. لیست تغییرات را به دقت تنظیم کنید.

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

او درست می‌گفت. دوست من مستند را با این ذهنیت نوشته بود که تنها هم‌تیمی‌هایش می‌خواهد آن سند را بخوانند در حالی که افراد دیگر نیز ممکن است روزی گذرشون به این سند بیوفته!

بعد از این تجربه، من همیشه به این موضوع فکر کردم که چطور چارچوب تغییرات را مستند کنم تا هر پیام مورد نظر را به درستی و روشنی منتقل کند.

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

3. موارد آسان را به صورت خودکار مدیریت کنید.

اگر انتظار دارید تا خواننده کد به شما بگوید که فلان خط با خط بالاییش تراز نیست، یا اینکه تغییراتی که اعمال کردید تست‌های سیستم را از کار انداخت، متاسفم اما شما زمان تیم را هدر داده‌اید! تست‌های خودکار (automated tests) باید در روند کاری شما وجود داشته باشند و تیم تنها زمانی باید کد شما را شروع به بررسی کند که تست‌های خودکار به درستی کار کنند و نتیجه درست را برگردانند.

در صورتی که تیم موافق پیاده‌سازی تست‌های خودکار نبود، می‌تونید با استفاده از چنگک‌های موجود در گیت (git pre-commit hooks) یا ابزار‌های دیگر روند بررسی برخی موارد رو به صورت خودکار مدیریت کنید.

(برای نمونه در این لینک می‌تونید ببینید که چطور قبل از commit کردن تغییرات می‌تونید به صورت خودکار کد رو مرتب کنید.)

4. دامنه تغییرات را کوچک نگه دارید.

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

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

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

5. تغییرات کدی و غیر کدی را جدا کنید.

گاهی پیش میاد که توسعه‌دهنده‌ دو خط کد رو تغییر میده و ویرایشگر بقیه قسمت‌های کد رو مرتب می‌کنه و همون کد برای بررسی به تیم ارسال می‌کنه؛ این کار باعث میشه تغییر اصلی در بین کلی تغییر ظاهری گم بشه و به چشم نیاد.

تغییراتی که به این شکل نامرتب و درهم و برهم هستند توهین به وقت خواننده است و هیچ توجیهی ندارد چون خواننده باید در ذهن خودش تشخیص بده تغییر رو‌به‌روش واقعا تغییر است یا تنها یک مرتب‌سازی ساده.

این نکته برای بازنویسی‌ هم درست است. (منظور از بازنویسی یا refactoring زمانی‌ست که کد نیازی به تغییر رفتار ندارد اما توسعه‌دهنده برای تمیزی یا بهینگی بیشتر کد را تغییر می‌دهد اما مراقب است که خروجی کد تغییر نکند.)

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

6. یک تغییر بزرگ را به چند تغییر کوچک بشکنید.

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

تصور کنید که یک برنامه‌نویس می‌خواهد مورد A را پیاده‌سازی کند و برای اینکار نیاز دارد تا موارد ‌B و C را تغییر دهد. اگر این تغییرات کم باشند مشکلی بوجود نمی‌آید در غیر این صورت بررسی این کد کار مشکلی خواهد بود.

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

به جای اینکه تمام تغییرات را یک‌جا اعمال کنید، می‌تونید ابتدا تغییرات وابسته را انجام دهید و بعد از اون، ویژگی جدید رو پیاده‌سازی کنید و در یک درخواست جدید به تیم ارسال کنید. اینطوری کار خواننده کد به مراتب راحت‌تر خواهد بود.

7. به انتقاد‌ها پاسخ دوستانه و سازنده دهید.

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

رویکرد درست اینه که نظر هم‌تیمی رو به با ذهنی خالی از احساس بررسی کنیم و به خودمون اجازه بدیم که نقطه‌نظر جدیدی رو بررسی کنیم؛ شاید واقعا حرفش درست بود!

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

8. زمانی که خواننده اشتباه می‌کند صبور باشید.

همونطور که شما می‌تونید کد با خطا بنویسید، خواننده هم می‌تونه برداشت اشتباهی نسبت به کار شما داشته و نقد نادرستی رو به کد وارد کنه.

خیلی از توسعه‌دهنده‌ها واکنش دفاعی نسبت به نقد کارشون دارند و فکر می‌کنند که خواننده کد قصد توهین به او رو داشته و صحبت‌هایی می‌کند که هیچ نزدیکی به واقعیت ندارد.

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

(در این مقاله تعدادی نکته برای بازنویسی کد بیان کردم که می‌تونید از اون‌ها استفاده کنید.)

9. پاسخ شفاف و مشخص دهید.

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

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

بعضی بسترها مثل GitHub یا GitLab امکانی رو فراهم می‌کنند تا یک یادداشت گذاشته شده رو به عنوان انجام شده در نظر بگیرید (resolve کنید)؛ در صورتی که این امکان نبود، به سادگی پاسخ دهید که:‌ "انجام شد" یا "تغییر کرد" یا هر چیزی که نشون بده یادداشت خواننده رو بررسی کردید.

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

10. زمان پاسخ را کوتاه نگه دارید.

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

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

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

نتیجه‌گیری

هرگاه در آینده لیستی از تغییرات رو برای بررسی آماده می‌کردید، حواستون به مواردی که سمت شما هستند باشه و طوری مدیریتشون کنید تا هم‌تیمی‌ها، مشارکت‌کننده‌ها و… از خوندن و بررسی کد شما لذت ببرند و درگیر حاشیه نشن.

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

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

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