روش های انتخاب اسم های خوب

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

  • از اسم هایی استفاده کنید که کاری که انجام میدن رو نشون میدن: اسم های شما باید طوری واضح باشن که نیازی به کامنت ها برای توضیح دادنشون نباشه، مثل timeElapsedInDays ،daysSinceCreation و ageInDays. معمولا کد باید خودش رو توضیح بده و تا حد ممکن از کامنت ها کمتر استفاده بشه. کامنت ها به نحوی به مرور زمان که کد ریفکتور میشه و منطق کد تغییر میکنه قدیمی میشن و برنامه نویس ها هم معمولا یادشون میره که اونها رو آپدیت کنن.
  • از دادن اطلاعات نادرست اجتناب کنید: در صورتی که متغیر شما درواقع حاوی یک array از کتاب ها هست bookList صداش نکنید، صرفا books کفایت میکن (چون لیست با آرایه فرق میکنه).
  • تفاوت ها رو به طور واضح و معنادار نشون بدید: اگه دوتا کلاس متفاوت دارید و اسم هاشون شبیه هم هستن، مثل BookInfo و BookData، شما صرفا خود اسم ها رو متفاوت انتخاب کردید در صورتیکه معنی اونها یکی هست. اسم های خاصی انتخاب کنید که مشخص کنه هدف هر کلاس چیه.
  • اسم هایی با تلفظ آسون / قابل تلفظ انتخاب کنید: بریم یه مثال بد ببینیم:

const yyyymmdstr = moment().format("YYYY/MM/DD");

حالا با یه مثال خوب مقایسش کنید، خودتون متوجه میشید:

const currentDate = moment().format("YYYY/MM/DD");

  • از اسم های ثابت و قابل جستجو استفاده کنید: شما بیشتر از وقتی که کد رو مینویسید اون رو میخونید. یه متغیر با اسم SECONDS_IN_DAY (ثانیه های تو یک روز) خیلی معنادار تر از 86400 هست و معنی این عدد رو بهتر نشون میده. همچنین اگه بعدا خواستیم اون رو پیدا کنیم راحت تر میتونیم این کار رو انجام بدیم.
  • اسم کلاس ها: کلاس ها باید دارای اسم یا عبارت اسمی باشن، مثل Customer ،Account و AccountParser. از استفاده از اسم هایی مثل Manager ،Processor ،Data یا Info که فعل یا خیلی کلی هستن اجتناب کنید.
  • اسم متد ها: اسم متد ها باید دارای فعل یا عبارت فعلی مثل addFunds ،deleteUser یا save باشن. Accessor ها و mutator ها باید اولشون get یا set بیاد.
  • برای هر کانسپت یک کلمه انتخاب کنید: استفاده همزمان از اسم هایی مثل fetch ،retrieve و get که همه یه کار میکنن میتونه گیج کننده باشه. بهترین کار اینه که یه کلمه انتخاب کنید و اون رو توی قسمت های مختلف کدتون استفاده کنید.
  • خودمونی نباشید: اگه اسم هایی که خیلی شوخی آمیز یا مربوط به یه فرهنگ خاص باشن رو انتخاب کنید، ممکنه برای بقیه افرادی که از اون فرهنگ نباشن یا حس شوخ طبعی متفاوتی داشته باشن جالب نباشه. مثل این میمونه که بجای ()abort از ()eatMyShorts استفاده کنیم.
  • از اضافه کردن زمینه های غیرضروری اجتناب کنید: اگه کلاس یا آبجکت شما به صورت توصیفی نام گذاری شده، دیگه نیازی نیست که از اسم اون به عنوان بخشی از متغیر های مربوط بهش استفاده کنید. مثال زیر یه نمونه بده:

const employee = {
employeeFirstName: "Daniel",
employeenLastName: "Rosenbaum",
employeeActive: true
};
function fireEmployee(employee) {
employee.employeeActive = false;
}

و مثال زیر خوبه:

const employee = {
firstName: "John",
lastName: "Smith",
active: true
};
function fireEmployee(employee) {
employee.active = false;
}

حالا در زیر بهترین روش های اسم گذاری برای فانکشن ها رو داریم:

  • فانکشن ها باید فقط یه کار انجام بدن و کوچیک باشن: زمانی که فانکشن ها توی کاری که انجام میدن دقیق تر و محدود تر هستن، بهتر میشه نحوه کار اونها رو فهمید، تست کرد و باهاشون کار کرد. همچنین خوانا تر و رفکتور کردنشون آسون تر میشه. همچنین با انتخاب یه اسم خوب خود-توصیف-گر هم میشن.
    در مثال زیر یه فانکشن بد رو داریم:

function phoneSubscribers(subscribers) {
subscribers.forEach(subscriber => {
const subscriberRecord = database.lookup(subscriber);
if (subscriberRecord.isActive()) {
phoneSubscriber(subscriber);
}
});
}

و در مثال زیر یه فانکشن خوب داریم:

function phoneActiveSubscribers(subscribers) {
clients.filter(isActiveSubscriber).forEach(phone);
}
function isActiveSubscriber(subscriber) {
const subscriberRecord = database.lookup(subscriber);
return subscriberRecord.isActive();
}

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

function addToDate(date, month) {
// ...
}
const date = new Date();
// It's hard to tell from the function name what is added
addToDate(date, 1);

و در مثال زیر یک اسم خوب برای فانکشن انتخاب شده:

function addMonthToDate(month, date) {
// ...
}
const date = new Date();
addMonthToDate(1, date);

  • از فلگ های بولین به عنوان پارامتر های فانکشن استفاده نکنید: اگه رفتار فانکشنتون کلا با توجه به مقدار یک فلگ تغییر میکنه، بهتره اون رو به دو فانکشن جدا تقسیم کنید. به عنوان مثال در صورتی که دیگه نشه اسم فانکشن رو ()doSomething (که میشه یه‌‎کاری انجام بده‌) گذاشت و بجاش باید ()doSomethingOrSomethingDifferentIfAFlagIsSet (که رسما معنی اسمش میشه یه کاری انجام بده یا درصورت ست شدن فلگ متفاوت یه کار دیگه انجام بده‌!) گذاشت، موقعش رسیده که به دوتا فانکشن تقسیم بشه.
    کد زیر رو ببینید:

function createFile(name, temp) {
if (temp) {
fs.create(`./temp/${name}`);
} else {
fs.create(name);
}
}

به جای کد بالا بهتره از کد زیر استفاده کنید:

function createFile(name) {
fs.create(name);
}
function createTempFile(name) {
createFile(`./temp/${name}`);
}

  • فانکشن ها رو جوری بنویسید که باعث ایجاد عوارض جانبی نشن: به طور خیلی خلاصه، یک عارضه جانبی وقتیه که مثلا موقع فراخوانی یک فانکشن یه چیزی تغییر کنه یا یه کاری انجام بشه که مربوط به مقدار هایی که فانکشن برمیگردونه نباشه. حالا این میتونه تغییر مقدار یک متغیر گلوبال، نوشتن به یک فایل و یا ایجاد یک سرویس کال باشه.
    البته زمان هایی هست که ممکنه استفاده از این اکشن ها نیاز باشه، مثل ایجاد یک سرویس کال برای گرفتن دیتا یا نوشتن نتیجه ها به یک فایل. در این حالت بهترین کار اینه که چنین کار هایی رو توی فانکشن های جداگونه پیاده سازی کنید و سعی کنید بقیه فانکشن ها رو تا اونجایی که میتونید بدون عوارض جانبی بنویسید.
    به عنوان مثال، فانکشن زیر یک متغیر گلوبال رو تغییر میده و این یعنی عوارض جانبی داره. (این میتونه کد مربوط به یک بازی باشه که موقعیت کاراکتر بازیکن یه جایی توی صفحه باشه) متغیر های playerX و playerY مختصات مربوط به موقعیت کاراکتر رو نشون میدن:

let playerX = 45, playerY = 100;
const moveRight = (numSlots) => {
playerX += numSlots;
}
moveRight(5);

توی کد بالا بهتره که x رو به عنوان پارامتر بگیریم و نتیجه خروجی فانکشن رو خارج از کد فانکشن به عنوان مقدار متغیر گلوبال اختصاص بدیم تا فانکشن هیچگونه عوارض جانبی نداشته باشه و مقدار هایی که برمیگردونه قابل پیش بینی باشن (که در نتیجه باعث میشه فرایند تست کردن فانکشن آسون تر باشه):

let playerX = 45, playerY=100;
const moveRight = (playerX, numSlots) => playerX + numSlots;
playerX = moveRight(playerX, 5);


نکته: عوارض جانبی و فانکشن های پاک (بدون عوارض جانبی) با جزئیات بیشتر توی فصل ۱۴: برنامه نویسی تابع محور بررسی میشن. یه مثال مهم دیگه اینه که موقع ایجاد تغییرات روی آبجکت ها، آرایه ها و لیست ها اونها رو کپی / کلون (clone) کنید و به طور مستقیم تغییرشون ندید.


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

if (serviceCall.state === "loading" && isEmpty(result)) {
// ...
}

مثال زیر یک فانکشن خوب رو نشون میده:

function shouldShowSpinner(serviceCall, result) {
return serviceCall.state === "loading" && isEmpty(result);
}
if (shouldShowSpinner(serviceCall, result)) {
// ...
}