اگر یادتان باشد در جلسه اول توضیح دادم که کد تمیز ویژگی های خاصی را دارد. این ویژگی ها بدین شکل هستند:
ساختار این دوره نیز به همین شکل است و هر فصل را به یکی از این موضوعات اختصاص داده ایم. امروز با نکته اول، یعنی نام گذاری، شروع خواهیم کرد. نام گذاری خود شامل سه بخش مهم است:
ما هر سه حالت را بررسی کرده و از هر کدام مثال های مختلفی را بررسی خواهیم کرد.
زمانی که بحث نام گذاری در برنامه نویسی مطرح می شود یک قانون کلی وجود دارد که بر روی تمام قوانین دیگر احاطه خواهد داشت و آن معنادار بودن نام های انتخاب شده توسط شما است. بسیاری از توسعه دهندگان (مخصوصا در ایران که آشنایی با زبان انگلیسی کمتر است) تصور می کنند که با انتخاب یک واژه انگلیسی معنادار، نامی عالی را انتخاب کرده اند. اگر این واژه انگلیسی معنادار از اصطلاحات برنامه نویسی و حوزه وب نیز باشد که فبها! از نظر این افراد بهترین نام را انتخاب کرده اند اما انتخاب نام معنادار به هیچ عنوان بدین معنی نیست. معنادار بودن نام انتخاب شده یعنی زمانی که فردی نام متغیر شما را می خواند باید بدون نگاه به کدهای دیگر تا حد زیادی متوجه بشود که کار آن متغیر چیست و چه مقداری را در خود نگه می دارد یا مثلا اگر کسی به نام تابع شما نگاه کند باید بدون نیاز به بررسی کدهای درون تابع، متوجه وظیفه اصلی آن تابع بشود. به طور مثال به کد زیر توجه کنید:
const us = new MainEntity(); us.process(); if (login) { // انجام فرآیندی خاص }
این کد قسمت خاصی از یک پروژه بزرگ است. با اینکه کد بالا تنها چند خط است و نام های انتخاب شده کلمات انگلیسی صحیح هستند اما برای من و شما که تمام کدها را نداریم اصلا معلوم نیست که چه خبر است و وظیفه این کد چیست! هر کسی با دیدن کد بالا سوالاتی از خودش می پرسد: MainEntity چیست؟ متد process چه کار می کند؟ مقدار login چیست و چه نوع داده هایی را قبول می کند؟ آیا login یک تابع خاص است و ما در حال بررسی وجود یا عدم وجود این تابع هستیم یا اینکه یک مقدار boolean است یا اینکه یک رشته است؟ حالا نسخه خوانای کد بالا را برایتان قرار می دهم:
const user = new User(); user.save(); if (isLoggedIn) { // انجام فرآیندی خاص }
درک این کد بسیار ساده تر است. ما در خط اول یک user یا کاربر جدید را ساخته ایم و در خط دوم این کار را ذخیره (save) کرده ایم (تمام کد را نداریم اما حدس می زنیم که این ذخیره سازی در پایگاه داده اتفاق می افتد). و در نهایت isLoggedIn (به معنی «آیا لاگین شده است؟») را داریم. از همین نام ساده (isLoggedIn) متوجه می شویم که مقدار آن حتما نتیجه بررسی لاگین بودن یا نبودن کاربر است و به احتمال بسیار زیاد با یک boolean سر و کار داریم.
زمانی که نام گذاری ما معنادار باشد، فرد دیگری که کدهای ما را می خواند به سادگی می تواند متوجه کلیت کار شود. ما برای درک کدهای بالا نیازی به داشتن سورس کد کل پروژه نداشتیم؛ مثلا نیازی به بررسی کلاس User نبود تا بدانیم دقیقا درون آن چه چیزی نوشته شده است. شاید بپرسید چرا باید برای من اهمیت داشته باشد که یک فرد دیگر بتواند کدهایم را بخواند؟ این سوال پاسخ های مختلفی دارد:
باید توجه داشته باشید که ما همیشه روی نام گذاری توافق نخواهیم داشت چرا که سلیقه هر فرد متفاوت است و تفاوت های فردی غیر قابل انکار است. نکته مهم اینجاست که کدهایتان معنادار و خوانا باشند. من سه نسخه از یک کد را برایتان آماده کرده ام:
const admin = new Admin(); const admin = new AdminUser(); const admin = createAdmin();
دو خط اول از کلاس ها استفاده کرده اند و خط سوم از یک تابع استفاده کرده است اما هر سه کد بالا کاملا واضح و خوانا هستند و با یک نگاه متوجه می شویم که این کد برای ساخت یک ادمین جدید است.
قبل از اینکه بخواهیم با مثال های خوب و بد نام گذاری آشنا شویم باید قوانین مربوط به آن ها را بررسی کنیم. من این قسمت به سه بخش مختلف تقسیم کرده ام:
متغیرها و ثابت ها و خصوصیت ها همگی data container یا نگهدارنده داده هستند، یعنی از آن ها برای ذخیره داده استفاده می کنیم بنابراین من بعضا در این دوره با نام data container به آن ها اشاره می کنم. داده های ذخیره شده در این data container ها از منابع مختلفی می آیند؛ به طور مثال ممکن است داده های وارد شده توسط کاربر باشد یا نتیجه اعتبارسنجی باشد یا آرایه ای از محصولات از پایگاه داده باشد و الی آخر. با این حساب برای این دسته از نام گذاری ها باید از «اسم» یا «عبارات کوتاه به همراه صفت» استفاده نمایید تا آنچه درون data container های ما است را توصیف کند. به طور مثال User (به معنی «کاربر») یک اسم است یا isValid (به معنی «معتبر است») یک عبارت است (طبیعتا استفاده از صفت اجباری نیست). البته boolean ها مانند isValid کمی بیشتر شبیه به نام گذاری توابع هستند.
برای نام گذاری توابع و متدها باید روش دیگری را اتخاذ کنیم. ما درون توابع و متدها هیچ داده ای را به صورت خاص ذخیره نمی کنیم بلکه کدهایی را داریم که باید اجرا شوند. حتی اگر درون تابع متغیری تعریف کرده باشید، آن متغیر پس از اجرای تابع از بین می رود و موقتی است. برای نام گذاری این دسته باید از «فعل» یا «عبارات کوتاه با صفت» استفاده کنیم. نام هایی مانند sendData (داده را ارسال کن) یا InputIsValid (ورودی معتبر است) نام های مناسبی هستند. نکته مهم وجود «فعل» در این دو نام است.
برای نام گذاری کلاس ها باید با طبیعت کلاس ها آشنا باشید. کلاس ها نقشه ای برای ساخت یک شیء خاص هستند. به طور مثال اگر کلاسی برای ساخت کاربرها داشته باشیم، می توانیم با استفاده از نمونه سازی از آن یک شیء کاربر دریافت کنیم. با این حساب برای نام گذاری آن ها باید از «اسم» یا «عبارات ساده با اسم» استفاده می کنیم. نام هایی مانند User یا RequestBody نمونه هایی از نام خوب هستند.
طبیعتا شما نیازی به حفظ کردن این دستور العمل ها ندارید بلکه به مرور زمان به این ساختارها عادت خواهید کرد و بدون اینکه نیازی به فکر کردن داشته باشید چنین نام هایی را انتخاب می کنید.
Casing به استفاده از حروف بزرگ و کوچک و علامت های آندراسکور و امثال آن اشاره می کند. ما در برنامه نویسی معمولا چهار Casing یا روش نوشتار مشهور را برای نام گذاری داریم:
طبیعتا این زبان برنامه نویسی است که مشخص می کند شما از کدام روش Casing استفاده می کنید. شاید بپرسید من توسعه دهنده جاوا اسکرپیت هستم، آیا نمی توانم از kebab-case استفاده کنم؟ از نظر فنی می توانید کدهایتان را با هر Casing ای که خواستید بنویسید اما پیروی از قرارداد های هر زبان برنامه نویسی، بخشی از روش نوشتن کد تمیز و خوانا می باشد بنابراین پیشنهاد می کنم همیشه از قرارداد های مشهور زبان یا فریم ورک مورد استفاده خود پیروی کنید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.