نوشتن کد قابل خواندن انسان: نامگذاری یا نامگذاری

من در مورد عنوان این پست به عقب و جلو رفتم ، اما در پایان ، نتوانستم در برابر مرجع هملت مقاومت کنم.
موضوع امروز در مورد نوشتن کد پاک و قابل خواندن است. من به چند دلیل به این موضوع اهمیت می دهم. هنگامی که کد خواندن/درک آن آسان تر است ، آسان تر است:
- حفظ کردن
- اصلاح کننده
- بحث کنید (با مشتری ، همکاران ، اردک لاستیکی و غیره).
موارد زیادی وجود دارد که من با کد قدیمی روبرو شده ام که نمی فهمم.
این تجربه ناامیدکننده علاقه من به یادگیری نحوه ساخت کد “بهتر” را نادیده گرفته است.
خبر خوب این است که مجموعه ای از پست های وبلاگ ، انجمن ها ، کتاب ها و مقالات در مورد نحوه نوشتن کد بهتر وجود دارد. چند نکته ای که دیده ام:
- نظرات را به کد خود اضافه کنید. نظرات که توضیح می دهند “چرا” بهتر از نظرات هستند که توضیح می دهند “چه”
- تست بنویسید
- متغیرهای خود را به وضوح نامگذاری کنید
- اصل مسئولیت واحد: هر عملکردی باید یک کار را به خوبی انجام دهد
- از شرط های پیچیده خودداری کنید
- پرونده ها را در 250 خط کد یا کمتر نگه دارید
من ادامه می دهم ، اما یک توصیه وجود دارد که واقعاً مرا تحت تأثیر قرار داده است و می خواهم در مورد آن بحث کنم. توصیه این بود: “از اعلامیه های عملکرد سنتی استفاده کنید و از عملکردهای نامگذاری شده بر روی موارد ناشناس استفاده کنید.”
این توصیه توجه من را به خود جلب کرد زیرا کد من با عملکردهای ناشناس همراه است. من نمی توانم تعداد کارکردهای نامشخص را که به آن منتقل شده ام حساب کنم .map
با .forEach
وت .reduce
روشها
فکر نمی کنم در این مورد تنها باشم. من بارها و بارها خوانده ام که توابع فلش و توابع ناشناس به شما کمک می کند تا کد را مختصر تر کند و این کوتاه بودن باعث می شود پرونده های کوچکتر ، که بخشی از نوشتن کد بهتر است ، درست است؟ خوب ، به نظر می رسد که مختصر و ناشناس لزوماً به معنای بهتر یا قابل خواندن نیست.
هرچه بیشتر در این مورد فکر می کنم ، بیشتر معقول می شود. “متغیرهای خوب” یکی از موارد گلوله برای دستیابی به کد واضح تر است. متغیرهای دارای نام های واضح به ما کمک می کنند تا داده های موجود در آنها را درک کنیم. این همچنین باید در مورد توابعی که نه تنها حاوی داده ها هستند ، بلکه اغلب آن داده ها را به نوعی دستکاری کنند.
بیایید به یک مثال کوچک که از دوره Frontendmaster ، “بنیادهای عمیق جاوا اسکریپت V3” ساخته کایل سیمپسون ، نویسنده سریال “You Don't Dannow JS” نگاه می کنیم ، نگاهی بیندازیم.
من قصد دارم دو اجرای مختلف را که برای تابعی به نام نوشتم به اشتراک بگذارم printRecords
بشر یکی از توابع نامگذاری شده و دیگری استفاده نمی کند.
عملکرد ، printRecords
باید:
- مجموعه ای از اعداد را بپذیرید (این شماره ها نشانگر شناسه دانشجویی هستند)
- با استفاده از شناسه دانشجویی ، هر سابقه دانشجویی را بازیابی کنید
- این سوابق را به صورت حروف الفبا با نام دانش آموزان مرتب کنید
- هر رکورد را در قالب زیر چاپ کنید:
Name (student Id): Paid (or Not Paid)
var currentEnrollment = [410, 105, 664, 375]
var studentRecords = [
{ id: 313, name: "Frank", paid: true, },
{ id: 410, name: "Suzy", paid: true, },
{ id: 709, name: "Brian", paid: false, },
{ id: 105, name: "Henry", paid: false, },
{ id: 502, name: "Mary", paid: true, },
{ id: 664, name: "Bob", paid: false, },
{ id: 250, name: "Peter", paid: true, },
{ id: 375, name: "Sarah", paid: true, },
{ id: 867, name: "Greg", paid: false, },
];
// Named Functions Version:
function printRecords(recordIds){
function findStudentRecords(recordId){
function getStudentRecordById(record){
return recordId == record.id;
}
return studentRecords.find(getStudentRecordbyId);
}
function alphabetizeRecordsByName(a,b){
return a.name > b.name ? 1: -1;
}
function printEachRecord(record){
console.log(
`${record.name} (${record.id}): ${record.paid ? 'Paid': 'Not Paid'}`
);
}
recordIds.map(findStudentRecords)
.sort(alphabetizeRecordsByName)
.forEach(printEachRecord);
}
//Anonymous Functions Version:
function printRecords(recordIds){
recordIds
.map((recordId) =>
studentRecords.find((studentRecord) => studentRecord.id == recordId)
)
.sort((a,b) => a.name > b.name ? 1: -1)
.forEach((student) => {
console.log(
`${student.name} (${student.id}): ${student.paid ? 'Paid': 'Not Paid'}`
)
})
}
printRecords(currentEnrollment);
// Console:
/*
Bob (664): Not Paid
Henry (105): Not Paid
Sarah (375): Paid
Suzy (410): Paid
*/
با نگاهی به این دو پیاده سازی در کنار هم در ویرایشگر من ، می توانم ببینم که نسخه نامگذاری شده printRecords
خطوط 1-23 را شامل می شود ، در حالی که نسخه ناشناس خطوط 1-12 را شامل می شود. برخی از این نتیجه از فرمت خودکار کدگذاری شده است که من استفاده می کنم ، اما بلافاصله مشخص است که نسخه ناشناس مختصر تر است.
هنوز ، وقتی به نسخه نامگذاری شده نگاه می کنم ، می فهمم که هر عملکرد در چه عملکردی دارد .map
با .sort
وت .forEach
روش در حال انجام است. لازم نیست خط کد را به صورت خط بخوانم. این درست در آنجا است: سوابق دانشجویی را پیدا کنید ، آنها را به صورت حروف الفبا با نام مرتب کنید ، هر رکورد را چاپ کنید. در مقابل ، نسخه ناشناس به من نیاز دارد تا به کد موجود در بدنه هر عملکرد نگاه کنم تا آنچه را که اتفاق می افتد درک کنم.
در این حالت ، من ترجیح می دهم 11 خط کد اضافی را برای یک تجربه بهتر در اصلاح این کد در جاده بگیرم.
کایل سیمپسون در سخنرانی خود اظهار داشت که حداقل سه دلیل برای انتخاب توابع نامگذاری شده بر روی موارد ناشناس وجود دارد:
-
Reference قابل اعتماد (به عنوان مثال اگر یک عملکرد نام دارد ، می تواند کارهایی مانند تماس با خود را برای یک راه حل بازگشتی انجام دهد)
-
ردیابی پشته اشکال زدایی بیشتر (اگر عملکرد دارای نام باشد ، ردیابی پشته آن را ارائه می دهد)
-
کد مستند سازی بیشتر
نظر شما چیست؟ آیا اگر این به معنای کد قابل خواندن بیشتر انسانی باشد ، از توابع ناشناس خودداری می کنید؟ آیا از تعداد خطوط کد به عنوان نشانگر اینکه آیا یک قطعه کد نیاز به بازنویسی دارد استفاده می کنید؟ چگونه اطمینان حاصل می کند که کد شما 2 ماه در جاده و فراتر از آن قابل خواندن است؟
** تصویر توسط Tumisu از Pixabay