کد خود را به خوبی کامنت‌گذاری کنید

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

کامنت‌گذاری 

1. کدها را طوری بنویسید که خودشان را توصیف کنند

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

نام‌گذاری متغییرها، توابع و کلاس‌ها

گرچه دست‌تان برای انتخاب روش نامگذاری کدتان، یا اصلا نداشتن هیچ قاعده و روشی باز است ولی این را از ما بپذیرید که با نامگذاری صحیح می‌توانید با قابل فهم‌تر نگهداشتن کد به نفع خودتان استفاده نمایید. چگونه؟ کافیست فقط به خاطر داشته باشید که نام‌های واضحی را انتخاب نمایید، نه با ترکیب مخفف‌های عجیب و غریب و استفاده از نام‌هایی که ممکن است مبهم باشند. اگر متغییر شما نمونه‌ای از یک کلاس VeryImportantCustomer را نمایش می‌دهد، بهتر است نام آن را $veryImportantCustomer بگذارید، و از انتخاب نام‌هایی مانند $customer و $vimpCust یا $tempcustomer اجتناب کنید. همچنین از داشتن غلط‌های املایی در نام‌های بلند نترسید IDE شما احتمالا به شما درباره متغییرهای استفاده نشده و دیگر تناقضات و ناهماهنگی‌ها هشدار می‌دهد. مطمئن باشید که نامگذاری مناسب به شما در فهمیدن چیزی که در کدتان قرار است اتفاق بیفتد خیلی کمک می‌کند.

Type hinting

PHP به شما اجازه می‌دهد تا نام‌های کلاس/رابط  یا کلمات کلیدی array / callable را کنار یک پارامتر تابع به عنوان راهنما قرار دهید. اینکار از فراخوانی تابع اشتباه ممانعت می‌کند اما این به عنوان تکه مهمی از اطلاعات برای هرکسی به خواندن کدتان کمک می‌کند. مجبور نیستید که بدنه تابع را بررسی و امتحان کنید تا بدانید که چگونه تابع را فراخوانی کنید. IDE شما احتمالا Type hintingها را تفسیر خواهد نمود  و از آنها برای توصیف توابع توسط popupها یا hintهایی که در حین کدنویسی به شما نمایش داده می‌شوند استفاده می‌کند. اگر هنوز متوجه نشدید که Type hinting چیست نگران نباشید، کد زیر را ببینید:

function arraysSum(array ...$arrays): array
{
    return array_map(function(array $array): int {
        return array_sum($array);
    }, $arrays);
}

با استفاده از قابلیت Type hinting در هنگام نوشتن متد یا تابع، قبل از نام پارامتر نوع آن را مشخص می‌کنیم و در صورتی که نوع آرگومان ارسالی با پارامتر تعریف شده متد تفاوت داشته باشد، خطا نمایش داده می‌شود. به عنوان توضیح بیشتر مثلا اگر نوع عددی را برای پارامتر تعریف کنیم، از ارسال مقادیر از نوع رشته و آرایه جلوگیری می‌شود و حتی اگر نام یک کلاس را قبل از پارامتر بنویسیم، باید شی ارسالی از نوع همان کلاس باشد. همین اندازه کافی است، برای اطلاعات بیشتر Type declaration در مباحث پیشرفته شی گرایی را مطالعه کنید. مفهوم دیگری که باید بدان اشاره شود Method visibility است. بخش مهمی از چگونگی نوشتن کد شی‌گرا تخصیص Method visibility مناسب به متدهای کلاس است. این‌کار از یک سو، نشان می‌دهد که کد کدام بخش از منطق باید درون کلاس بماند و نباید به سایر کلاس‌ها در برنامه نمایش داده شود. از سوی دیگر، متدهای کلاس خاصی را به دسترسی عمومی می‌رساند تا بتوان آن‌ها را از خارج از کلاس فراخواند و با سایر قسمت‌های برنامه ارتباط برقرار کرد. اگر در کدی که می‌نویسید به خوبی به Scope (محدوده دسترسی) توجه کرده باشید، خواهید دید که سایر توسعه دهندگان خیلی سریع و راحت می‌توانند بفهمند که چگونه با کلاسی که شما توسعه داده‌اید کار کنند. آن ها خواهند دانست که چندین متد public وجود دارد که می توانند در کدهایشان از آنها استفاده کنند.

2. تعادل را حفظ کنید

البته شما ممکن است احساس کنید که خود کد به اندازه کافی واضح نیست و نیاز به توضیحات اضافی دارد. این امر به ویژه هنگامی مهم است که شما یک بخش پیچیده از Business logic را پیاده‌سازی می‌کنید، انجام محسبات پیچیده را اجرا می‌کنید یا فقط از دستوراتی استفاده می‌کنید که درک آن‌ها در اولین نگاه سخت است (مانند الگوهای عبارات باقاعده (Regular Expression)، تبدیلات آرایه و ...). در چنین مواردی نوشتن یک کامنت کوتاه مطمئنا به دانستن چیزی که اتفاق خواهد افتاد کمک می‌کند. از سوی دیگر، بلاک‌های کامنت نباید به خاطر ضعیف بودن کدها نوشته شوند. اگر کد شما شامل تعداد زیادی حلقه یا ساختارهای کنترلی است و حتی خودتان نمی‌توانید بدون تحلیل آن به مدت چند دقیقه به نحوه کار آن پی ببرید، رها کردن آن به همان شکل کد با چند خط کامنت بهترین راه حل نیست. به جای اینکه با کامنت‌گذاری آن را توضیح دهید، تلاش کنید تا آن را مجددا بنویسید. به غیر از بلاک‌های کد پیچیده، قسمت‌هایی از کد نیز وجود دارد واضح هستند و هیچ منطق پیچیده خاصی را نشان نمی‌دهند. برخی از توسعه دهندگان تمایل دارند تا حتی برای این بخش‌های برنامه نیز بلاک کامنت بگذارند، نیازی به اینکار نیست. به مثال زیر توجه کنید:

<?php
    class Deposit {

        /**
         * The deposit owner.
         *
         * @var string
         */
        private $_owner;

         /**
         * The deposit amount.
         *
         * @var float
         */
        private $_amount;

        /**
         * The date when the deposit was opened.
         *
         * @var DateTime
         */
        private $_dateOpened;

        /**
         * Class constructor.
         *
         */
        public function __construct() {
            //...
        }

        /**
         * Sets the deposit owner.
         *
         * @param string $owner The deposit owner name.
         */
        public function setOwner($owner) {
            $this->_owner = $owner;
        }
?>

به خاطر داشته باشید که کسی که دارد کد شما را می‌خواند معمولا یک توسعه‌دهنده است، پس بدون کامنت نیز قادر به درک این است که فیلد _owner از کلاس Deposit مالک سپرده را نمایش می‌دهد. به همین دلیل است که قرار دادن کامنت‌های اضافی برای بخش‌هایی از کد به جای اینکه به کسی که در حال خواندن کد است کمک کند، حتی می‌تواند خوانایی را کمتر کند . کامنت اغلب در بخش‌های ساده دیگر کد شما غیرضروری هستند، نه فقط در فیلدهای کلاس یا متدهای معمول (مانند سازنده‌ها، getterها و setterها). به مثال زیر توجه کنید:

<?php

public function showUserDetails() {
    $userId = $this->Session->read('userId');
    $userData = $this->getUserData($userId);
    if(!$user->isActive()) {
        throw new Exception("The user account hasn't been activated.");
    }

    //...
}
?>

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

<?php
/**
 * Shows the details of the user that is currently
 * logged in.
 *
 */
public function showUserDetails() {
    //get the current user from session
    $userId = $this->Session->read('userId');   

    //load the user data from database
    $userData = $this->getUserData($userId);

    //check if the user has an active account
    if(!$user->isActive()) {
        throw new Exception("The user account hasn't been activated.");
    }

    //...
}

?>

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

3. DocBlockها

همانطور که در مثال‌های بالا مشاهده نمودید، برخی بلاک‌های کامنت دارای خطوطی هستند که کلمات کلیدی دارند با کاراکتر @ شروع شده‌اند، به این کلمات تگ می‌گویند . به عنوان مثال از @var برای مشخص کردن نوع فیلد کلاس و از @param برای مشخص کردن نوع پارامتر متد یا تابع استفاده می‌شود. همچنین با استفاده از تگ @return نوع مقدار بازگشتی از متد را می‌توان مشخص نمود. تگ‌های دیگری نیز هستند که اطلاعات بیشتری را درباره برنامه یا بخشی از کد نمایش می‌دهند برای مثال نام توسعه‌دهنده، پکیج، نوع لایسنس و ... را می‌توان با استفاده از تگ‌های PhpDoc مشخص کرد. اگر می‌خواهید درباره DocBlockها بیشتر بدانید، توصیه می‌کنیم راهنمای مستندنویسی را مطالعه نمایید. تگ‌های DocBlocks حاوی اطلاعاتی هستند که نمی‌توانند در خود کد مورد استفاده قرار بگیرند. مشخص کردن نوع پراپرتی (property) کلاس یا مقدار بازگشتی تابع مخصوصا به دلیل اینکه در اغلب IDEها توسط باکس‌هایی در هنگام استفاده از آن‌ها به عنوان راهنما نمایش داده می‌شود. البته می‌توانید از متن توضیحی نیز استفاده کنید که در هنگام استفاده از بیرون از فایل و مستندسازی بسیار مفید هستند. اگر کد به آسانی قابل‌فهم است و نیازی به تولید مستندات توسعه‌یافته ندارید، فقط تگ‌هایی را استفاده کنید که اطلاعات بیشتری درباره نوع متغییرها و مقادیر بازگشتی تولید می‌کنند. در نتیجه، کد بیش از حد پیچیده نخواهد شد.

<?php
    class Deposit {

        /**
         * @var string
         */
        private $_owner;

         /**
         * @var float
         */
        private $_amount;

        /**
         * @var DateTime
         */
        private $_dateOpened;

        //...

        /**
         * @param string $owner
         */
        public function setOwner($owner) {
            $this->_owner = $owner;
        }
?>