اصول کامنت گذاری در کد‌ها

2250
کامنت گذاری در کد

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

برنامه‌های کامپیوتری دو مخاطب بسیار متفاوت دارند:

  1. کامپایلرها و مفسرها که کامنت‌ها را نادیده می‌گیرند و اجرای همه برنامه‌های صحیح برای آن‌ها به یک اندازه آسان است.
  2. خوانندگان انسانی که درک برخی از کدها را سخت‌تر از دیگر کدها می‌دانند و به دنبال کامنت‌هایی برای کمک به درک آن‌ها هستند.

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

قانون ۱: کامنت‌ها نباید کد را تکرار کنند

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

if (x > 3) {
   ...
} // if

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

کامنت‌هایی که هیچ اطلاعاتی اضافه نمی‌کنند ارزش منفی دارند؛ زیرا:

  • به‌هم‌ریختگی بصری ایجاد می‌کنند
  • برای نوشتن و خواندن وقت می‌گیرند
  • می‌توانند قدیمی و منسوخ شوند

به عنوان مثال کامنت گذاری در کد زیر نه‌تنها هیچ اطلاعاتی اضافه نمی‌کند، بلکه هزینه نگهداری را نیز تحمیل می‌کند:

i = i + 1;         // Add one to i

سیاست‌هایی که نیاز به کامنت برای هر خط کد را توصیه می‌کنند، در Reddit مورد تمسخر قرار گرفته‌اند 🙂

// create a for loop // <-- comment
for // start for loop
(   // round bracket
    // newline
int // type for declaration
i    // name for declaration
=   // assignment operator for declaration
0   // start value for i

قانون ۲: کامنت‌ها کد نامفهوم را توجیه نمی‌کنند

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

private static Node getBestChildNode(Node node) {
    Node n; // best child node candidate
    for (Node node: node.getChildren()) {
        // update n if the current state is better
        if (n == null || utility(node) > utility(n)) {
            n = node;
        }
    }
    return n;
}

در این مثال نیاز به کامنت را می‌توان با نام‌گذاری بهتر متغیر حذف کرد:

private static Node getBestChildNode(Node node) {
    Node bestNode;
    for (Node currentNode: node.getChildren()) {
        if (bestNode == null || utility(currentNode) > utility(bestNode)) {
            bestNode = currentNode;
        }
    }
    return bestNode;
}

کد بد را کامنت‌گذاری نکنید، آن را بازنویسی کنید.

The Elements of Programming Style

قانون ۳: اگر نمی‌توانید یک کامنت واضح بنویسید، ممکن است کد مشکل داشته باشد

بدنام‌ترین کامنت در کد منبع یونیکس کامنتی است که قبل از برخی کدهای context-switching وجود داشت: «انتظار نمی‌رود شما این را بفهمید.» متأسفانه بعداً معلوم شد که Dennis Ritchie و یکی از نویسندگان، Ken Thompson، خودشان آن کد را درک نکرده بودند و بعداً مجبور شدند آن را بازنویسی کنند.

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

ممکن است علاقه‌مند باشید: 5 زبانی که احتمالاً تا سال 2030 منسوخ شده‌اند

قانون ۴: کامنت‌ها باید سردرگمی را از بین ببرند، نه اینکه باعث آن شوند

برای توضیح این قانون به نقل این داستان از کتاب هکرها: قهرمانان انقلاب کامپیوتری اثر Steven Levy بسنده می‌کنیم:

پیتر سامسون از افزودن کامنت‌ها به کد منبع خود امتناع می‌کرد. یکی از برنامه‌هایی که سامسون به‌خوبی توزیع کرده بود، صدها دستورالعمل به زبان اسمبلی را به همراه داشت و تنها یک کامنت در کنار یک دستور که حاوی عدد ۱۷۵۰ بود گذاشته شده بود. کامنت RIPJSB بود. افراد دیگر معنای آن را متوجه نشدند تا اینکه کسی فهمید که ۱۷۵۰ سال فوت باخ است و آن کامنت مخفف Rest In Peace Johann Sebastian Bach است.

پس اگر کامنت شما به جای از بین بردن سردرگمی باعث آن می‌شود، آن را حذف کنید.

قانون ۵: کد unidiomatic را در کامنت‌ها توضیح دهید

کد unidiomatic کدی است که طبق رسم‌الخط مرسوم زبان برنامه‌نویسی نوشته نشده است. ایده خوبی است که کدی که ممکن است شخص دیگری آن را غیرضروری یا زائد بداند را کامنت‌گذاری کنید. به عنوان مثال کد زیر را در نظر بگیرید:

final Object value = (new JSONTokener(jsonString)).nextValue();
// Note that JSONTokener.nextValue() may return
// a value equals() to null.
if (value == null || value.equals(null)) {
    return null;
}

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

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

قانون ۶: لینک‌هایی به منبع اصلی کد کپی‌شده ارائه دهید

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

  • این کد چه مشکلی را حل کرده است
  • چه کسی کد را ارائه کرده است
  • چرا این راه‌حل توصیه می‌شود
  • نظر کامنت‌گذاران در مورد آن چه بوده است
  • آیا هنوز این کد کار می‌کند
  • چگونه می‌توان آن را بهبود بخشید

این کامنت را در نظر بگیرید:

/** Converts a Drawable to Bitmap. via https://stackoverflow.com/a/46018816/2219998. */

دنبال کردن لینک نشان می‌دهد که:

  • نویسنده کد Tomáš Procházka است که جزء ۳٪ برتر Stack Overflow قرار دارد.
  • یک کامنت‌گذار بهینه‌سازی را ارائه می‌دهد که قبلاً در مخزن گنجانده شده است.
  • یکی دیگر از کامنت‌گذاران راهی را برای جلوگیری از حالت‌های خاص (edge case) پیشنهاد می‌کند.

کامنت قبلی را با این کامنت مقایسه کنید:

// Magical formula taken from a stackoverflow post, reputedly related to
// human vision perception.
return (int) (0.3 * red + 0.59 * green + 0.11 * blue);

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

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

افراد بسیاری از کدها را از پرسش و پاسخ‌های Stack Overflow کپی می‌کنند. این کدها تحت مجوز Creative Commons قرار می‌گیرند که نیاز به ذکر منبع دارند. یک ارجاع در کامنت این نیاز را برآورده می‌کند.

به طور مشابه، شما باید به آموزش‌هایی که برای شما مفید بوده‌اند ارجاع دهید، هم به عنوان تشکر از نویسنده و هم اینکه بتوان آن‌ها را دوباره پیدا کرد:

// Many thanks to Chris Veness at http://www.movable-type.co.uk/scripts/latlong.html
// for a great reference and examples.

قانون ۷: هنگامی که درج پیوندهایی به مراجع خارجی می‌تواند مفید باشد از آن‌ها استفاده کنید

البته همه ارجاعات مربوط به Stack Overflow نیست:

// http://tools.ietf.org/html/rfc4180 suggests that CSV lines
// should be terminated by CRLF, hence the \r\n.
csvStringBuilder.append("\r\n");

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

قانون ۸: هنگام دیباگ کردن، کامنت‌های خود را اضافه کنید

کامنت‌ها نه‌تنها هنگام نوشتن کد، بلکه هنگام اصلاح و دیباگ کردن نیز باید به کد اضافه شوند. این کامنت را در نظر بگیرید:

// NOTE: At least in Firefox 2, if the user drags outside of the browser window,
  // mouse-move (and even mouse-down) events will not be received until
  // the user drags back inside the window. A workaround for this issue
  // exists in the implementation for onMouseLeave().
  @Override
  public void onMouseMove(Widget sender, int x, int y) { .. }

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

ارجاع به issue tracker‌ها نیز می‌تواند مفید باشد:

// Use the name as the title if the properties did not include one (issue #1425)

با وجود اینکه می‌توان از git blame برای یافتن کامیتی که در آن یک خط اضافه یا اصلاح شده است استفاده کرد، اما پیام‌های commit معمولاً مختصر هستند و مهم‌ترین تغییر (به عنوان مثال رفع مشکل 1425#) ممکن است بخشی از آخرین commit (مثلاً انتقال یک روش از یک فایل به فایل دیگر) نباشد.

ممکن است علاقه‌مند باشید: یک چیت‌شیت برای شروع کار با گیت و گیت هاب

قانون ۹: از کامنت‌ها برای علامت‌گذاری پیاده‌سازی‌های ناقص استفاده کنید

ممکن است وسوسه‌انگیز باشد که نقص‌های شناخته‌شده در کد خود را به اشتراک نگذاریم، اما بهتر است این موارد را صراحتاً بیان کنیم. به‌عنوان مثال در یک کامنت TODO:

// TODO(hal): We are making the decimal separator be a period, 
// regardless of the locale of the phone. We need to think about 
// how to allow comma as decimal separator, which will require 
// updating number parsing and other places that transform numbers 
// to strings, such as FormatAsDecimal

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

جمع‌بندی

امیدوارم مثال‌های بالا نشان داده باشند که کامنت‌ها، کد بد را توجیه یا اصلاح نمی‌کنند، بلکه کد خوب را با ارائه‌ی نوع متفاوتی از اطلاعات تکمیل می‌کنند. Jeff Atwood، یکی از بنیان‌گذاران Stack Overflow در جایی گفته است: «کد به شما می‌گوید چگونه، کامنت‌ها به شما می‌گویند چرا»

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

آموزش برنامه نویسی با کوئرا کالج
کوئرا بلاگ

اشتراک در
اطلاع از
guest

3 دیدگاه‌
قدیمی‌ترین
تازه‌ترین بیشترین واکنش
بازخورد (Feedback) های اینلاین
View all comments
سعید
2 سال قبل

ممنون از مطلب خوبتون (:

iamliana
iamliana
10 ماه قبل

سلام عالی بود تنک