Clean Code (بخش دوم)

در ادامه طبق روند کتاب جلو میریم. قرار توی این پست در مورد اولین نکته مهم که پایه و اساس یک فاکشن، یا کد، یا برنامه، یا هر متغیری هست صحبت کنیم. هدف این بخش کتاب این که کد هایی که شما می نویسین مثل خوندن یه روزنامه باشه(زمانی که روزنامه می خونین سرتون به سرعت روی خطوط حرکت می کنه) خود کتاب از واژه Quick Skim استفاده می کنه. تا به این ترتیب نه تنها خودتون در آینده از خوندن کداتون لذت ببرین، حتی بقیه ام خیلی راحت کداتونو بخون و هدف هر بخش از کد، فاکشن یا متغییر رو بفهمن.Meaningful Namesاز اینجا به بعد قصد داریم این دانش و آگاهی رو پیدا کنیم که نام های معنا دار چی هستن و چجوری باید نام های معنا دار انتخاب کرد و اصلا فرق بین نام معنا دار با نامه های نامناسب یا بی معنی چی هستش. و در نهایت با ایده کلی چگونگی انتخاب اسم اشنا بشیم. مطمئنا مفاهیم پیش رو بعد مدتی کد نویسی تا حدی توسط برنامه نویس رعایت میشه ولی ممکنه این رعایت کردن از نوع آگاهانه نباشه برای همین به بهترین شکل خودش اعمال نشه.Intention-Revealing Namesمهم ترین نکته در این بخش انتخاب اسامی است که مقصود خودشون رو نشون بدن. تقریبا این نکته پایه و اساس باقی نکات و مفاهیمی است که در ادامه می بینیم. نام یک متغیر، کلاس یا فانکشن باید بتونه دلیل وجودی، کاری که داره انجام میده، جا و نحوه ی استفاده شو توصیف کنه. در واقع جواب این سوال ها باید توی کد وجود داشته باشه بعنی اسامی و در انتزاع بالا تر خود کد باید بتونه خودش رو توصیف(کلمه ای که کتاب انتخاب کرده explicit بودنه) کنه.برای مثال d می تونه هرکدوم از متغیر های زیر باشه:int d; // elapsed time in days ----------------------------------------------- int elapsedTimeInDays; int daysSinceCreation; int daysSinceModification; int fileAgeInDays;نکته ای که وجود داره اگر مجبور بودید برای یک اسم کامنت بذارین تا مفهومش رو منتقل کنین (اسم می تونه در غالب فاکشن یا هر چیز دیگه باشه) اون اسم اصل نام گذاری معنادار و نقص کرده.Avoid Disinformationما همیشه حتی توی صحبت روزمره هم سعی می کنیم از الفاظی استفاده کنیم که مخاطب رو دچار سوء تفاهم نکن و مقصود مارو به درستی منتقل بکنن.در برنامه نویسی هم رعایت این نکته مهم چون می تونه باعث کج فهمی بشه ما می تونیم از اسمی مثل android استفاده کنیم ولی این ممکنه مفهوم درستی رو منتقل نکنه حتی زمانی که توی محیط اندرویدی باشید.مثال های دیگر: ممکنه accountList واقعا یک List نباشه مارو در تشخیص تایپ دچار اشتباه کنه ولی accountGroup یا BunchOfAccounts می تونه اسم بهتری باشه.اسامی که در کلماتشون تفاوت کمی وجود داره اسامی مناسبی نیستند. برای مثال پیدا کردن تفاوت بین این اسم XYZControllerForEfficientHandlingOfStrings و اسم مشابه دیگه که مثل این اسم XYZControllerForEfficientStorageOfStrings هست کار راحتی نیست.و هر مثالی از این دست مشکلات که به ذهن شما میرسه؟؟Make Meaningful Distinctionsما همیشه باید سعی کنیم تفاوتی هایی که ایجاد می کنیم، معنایی رو منتقل کنند در غیر اینصورت ما اصل معنا دار بودن رو نقض کردیم و تفاوتی که ایجاد کردیم کارایی و ارزش کد رو پایین میارن. برای مثال از نام klass به جای class استفاده کنیم و علاوه بر اینکه تفاوت ما معنادار نیست ممکنه ما دچار مشکلات کامپایلری هم بشیم.نکات مهم:استفاده از اعداد در کنار حروف مناسب نیستد و با اینکه تفاوت بین اسامی ایجاد کرده اند ولی تفاوت معنا دار نیست. مانند a1اسامی مثل Data یا Info و کلماتی مثل a، an و the نیز اسامی مناسبی برای ایجاد تفاوت نیستند. حالا اگه شما می تونین تفاوت بین این اسامی رو بگین :getActiveAccount();getActiveAccounts();getActiveAccountInfo();مشخصه که نمیشه با یقین تفاوت هاشون و ماهیتشون رو به زبون اورد.مثال بیشتر: moneyAmount, money - customerInfo, customer and so on...Use Pronounceable Names باتوجه به کار کرد مغز انسان، بخشی مهمی از مغز به کلمات اختصاص داده شده و هر کلمه دارای بار معنایی است. بنابراین استفاده از اسامی معنادار کمک می کنه تا کد ما داری خوانایی بیشتری باشه برای همین استفاده از اسامی معنا دار بهترین گزینه است و استفاده از اسامی معنا دار یعنی استفاده از اسامی قابل تلفظ.class DtaRcrd102 {private Date genymdhms;private Date modymdhms;private final String pszqint = "102";};class Customer {private Date generationTimestamp;private Date modificationTimestamp;;private final String recordId = "102";};Pick One Word per Conceptتا اینجا یاد گرفتیم که اسامی باید چه ویژگی هایی داشته باشن و چه ویژگی هایی نداشته باشن. مشخصه که با رعایت مفاهیم بالا تا حدی انتخاب اسامی مون بهتر میشه ولی بیاین یک سطح انتزاعمون رو بیاریم بالاتر، به کلماتی مثل get یا fetch دقت کنین. اگه تو کلاس های مختلف از هر کدوم استفاده کنیم زمانی که تعداد کلاس ها بره بالا ممکنه برای کسی دیگه ای که کد های مارو می بینه حتی بعد مدتی برای خودمون این انتخاب اسم گیج کننده بشه. بخصوص زمانی که هر کدوم از اونا بخوان یه کار متفاوت هم انجام بدن.بنابراین بهتره که برای انتخاب اسم برای یک موضوع و انتزاع هم دقت کنیم.برای مثال فانکشنی که در یک کلاس اطلاعات مربوط به اون کلاس رو بر می گردونه فقط با get نام گذاری بشه. نکته دیگه ای که توی این مفهوم وجود داره اینه که علاوه بر این که نباید از دو اسم برای یک انتزاع استفاده کرد همین طور نباید از یک اسم برای دو کار و انتزاع مختلف استفاده کرد برای مثال فکر کنین ما از اسم add برای ساخت یک مقدار جدید در تمام کلاس ها استفاده می کنیم و این یعنی ثبات (consistency) و ما هم به دنبال همین هستیم. و حالا یک کلاس جدید می سازیم که از فاکشن add به جای ساختن یک مقدار جدید، یک مقدار به مقدار قبلی در یک آرایه اضافه می کنیم ظاهرا همه چی درسته ولی باید بدونیم که در واقع ما عملیات insert یا append انجام دادیم پس باید تو این کلاس از append یا insert به عنوان اسم فانکشنمون استفاده کنیم. فکر می کنم تا حدی متوجه شده باشیم که چه اسامی باید انتخاب بشن و چجوری باید انتخاب بشن ولی چنتا نکته وجود داره که خوب گفته بشه:دقت کنید که استفاده از اسامی مناسب جست و جو در پروژه رو برای ما آسون می کنه بنابراین اسامی انتخاب کنین که یسری ویژگی های بالا رو داشته باشن یسری رو نداشته باشن و search-friendly باشن. اسمی مثل حرف e که جز حروف پر تکرار بد ترین انتخاب می تونه باشه.همین طور که هر متنی مخاطب داره مخاطب کد های ما برنامه نویس ها هستن. با همین استدلال برای انتخاب اسم ها می تونین دو استراتژی رودر نظر بگیرید: انتخاب اسم بر اساس راه حل (Use Solution Domain Names):اسم می تونه یک اصطلاح در علم کامپیوتر، اسم یک الگوریتم، یک اصطلاح ریاضی یا هر چیز مرتبط دیگه ای باشه. برنامه نویسی نداریم که ندونه JobQueue چه مفهومی داره. بنابراین بهترین استراتژی برای اتنخاب اسم، انتخاب بر اساس راه حل هستش.انتخاب اسم بر اساس مشکل (Use Problem Domain Names): راه دیگر انتخاب اسم بر اساس مشکلی هست که که حل می شه. تنها مشکل این استراتژی زمانی هست که شخص دیگه ای بخواد روی کد کار کنه بنابراین باید در مورد مشکل از شخصی که توی اون پروژه تجربه داشته سوال بپرسه.جدا کردن دامنه راه حل و مشکل بخشی از کار یک برنامه نویس یا طراح خوبه پس باید روش دقت بشه.نکته: زمانی که تمرکز یه کد بیشتر روی حل یک مشکل هست بهتره که اسم از دامنه مشکلات انتخاب بشه.درسته که رعایت نکات و مفاهیم بالا می تونه کمک کنه اما علاوه برا نکات بالا وجود یک مهارت توصیفی خوب در فرد و وجود یک پیشینه فرهنگی مشترک هم می تونه کمک زیادی کنه تا کد از خوانایی زیادی برخوردار باشه. که این مسائل بیشتر مربوط به مسائل آموزشی هستن تا مسائل تکنیکی کار. و در انتهای این بخش کتاب میگه "این قوانین رو پیروی کنین اگه خوانایی کدتون بیشتر نشد."با رعایت این مفاهیم ممکنه زمان بیشتری هنگام کد زدن از شما بگیره ولی با هزینه کردن این زمان هنگام کد زدن مسلمه در آینده در هنگام تغییرات یا استفاده دوباره از کد صرفه جویی میشه. البته تمام این نکات بدون تمرین عملی و تکرار عملا به درد نمی خورن و باید هنگام کد زدن بهشون فکر کنین، رعایتشون کنین، تو انتخاب اسامی دقت کنین اگر اسم بهتری انتخاب کردین برگردین و جایگزینش کنین. تو این بخش سعی کردم نکات مهم و بدرد بخور رو تا حد امکان منتقل کنم و در عین مفید بودن، خلاصه هم باشه. اگه نکته ای یا مشکلی یا پیشنهادی می بینین خوبه که درمیون بذارید تا بقیه ام استفاده کنن. تو مبحث های بعدی سعی می کنم مبحث های کاربردی و بدرد بخور دیگرو مطرح کنم تا روز به روز کدامون تمیز بشه. تو این پست نشد نقل قولی رو بیارم سعیمو می کنم تو پست های بعدی یه جایی برای نقل قول در نظر بگیرم.توئیتر من: Nima Shirinzadeh