7 Заповідей Читабельного Коду
Усі статті, обговорення, новини про Front-end — в одному місці. Підписуйтеся на телеграм-канал!
Про що ця стаття..
..і чому це важливо навіть для тих, хто ніколи не торкався, і можливо не доторкнеться до JS/TS? Хоча деякі мови вигідно/невигідно відрізняються, більшість все ж таки залишається дуже схожою, therefore, багато чого з цього тексту може бути вам корисним. Також, не слід забувати що мова — це лише інструмент, і головний фактор, який впливає на якість/читабельність коду — це ви та ваш підхід до його написання. Тож зараз ми розберемо на прикладах, деякі базові «помилки», уникання яких допоможе не тільки вашій команді, але й вам самому через деякий час.
true чи не true, ось у чому питання
Розглянемо код. Як думаєте, що з ним не так?
function isGoodBoy(boy) {
if (boy.isGood) {
return true;
} else {
return false;
}
}
Багато хто скаже — з ним все добре, і насправді так і є. Проте, якщо уважно вивчити його, можна зрозуміти, що ми робимо забагато «зайвих рухів», які не просто не роблять картину ліпше, а й псують її. Навіщо використовувати if-else, якщо значення умови — напряму зв’язане зі значенням, що повертається. Простий аналіз вашого коду — завжди викриє такі недоліки.
function isGoodBoy(boy) {
return boy.isGood;
}
let me use const
function calculation(a, b, c) {
let division = a / b;
return division * c;
}
Дивно, проте велика частина людей ігнорує той факт що в ES6, разом із let, 7 років назад, прийшов const. Звичайно, іноді без let нікуди, — хоча це спірно :D, тому я завжди рекомендую правило:
Якщо змінна може бути const, вона МАЄ бути const.
Чи варто ризикувати надійністю та читабельність коду, — а іноді доволі важко вгледіти за змінною, яка постійно перевизначається,
function calculation(a, b, c) {
let division = a / b;
// some code
division = 'oops';
// some code
return division * c;
}
замість того щоб писати на 2 літери більше. Відповідь за вами.
function calculation(a, b, c) {
const division = a / b;
return division * c;
}
Не став мені умови, тим паче такі!
Чи бачили ви колись умовні оператори з такими умовами?
if (user.tags[0].find(({name, enc}) => name === 'user' && enc === 'sha256')) {
// do something
}
— Конкретно такі, можливо що ні, проте великі та незрозумілі умови — це дуже поширена проблема. Ще дуже давно я зрозумів, що якщо ставити такі вирази в if, можна залишитися не лише без readable коду, а й без друзів. Це стосується не лише if, але усіх місць де використовується вираз, який перетворюється на значення boolean. Гарна контрміра — виносити всі ці вирази у змінні, що мають логічні та зрозумілі назви. Consider:
const userTagIsCompatible = user.tags[0].find(({name, enc}) => name === 'user' && enc === 'sha256');
if (userTagIsCompatible) {
// do something
}
Who else if not me?
function handleEvent(event) {
if (event.metadata) {
if (event.type === 'mouse') {
// do something
return 'if string';
} else {
// do something else
return 'else string';
}
}
return 'default case string';
}
Цю тему дуже часто висвітлюють всеможливі блогери та ютубери, просто тому, що для молодих розробників, це може бути щось не очевидне. Менеджмент if-else’ів — це доволі велика тема, проте, якщо говорити по суті — намагайтеся використовувати guard кейси, та реверсувати if з else, за допомогою перевертання умови.
function handleEvent(event) {
// guard case
if (!event.metadata) return 'default case string';
if (event.type === 'mouse') {
// do something
return 'if string';
}
// do something else
return 'else string';
}
Часто, else може навіть не знадобитись, що своєю чергою, зменшить nesting, і збільшить readability.
Decoupling та єдина відповідальність
Зіграймо в гру! На рахунок 3 всі, у кого були функції більше ніж 100 рядків, — стрибне! Насправді це погана ідея, тому, що Землю, скоріш за все, знесе з орбіти сонця. Всі хто мав/має таку функцію думав — «Можливо, все ж таки, винести трішки коду», проте ця ідея, на жаль, так і залишається ідеєю. Так от. Це ОБОВ’ЯЗКОВО треба робити, це не тільки допомагає проєкту триматися на курсі best practice, а ще тому, що нову «модернізовану» функцію можна буде читати як вірш Шевченка.
function read(userInput) {
if (userInput.rights.read) {
const sanitizedInput = sanitizeInput(userInput.content);
return processInput(sanitizedInput)
}
return handleInputWithoutRights(userInput);
}
Magic strings, або «Як воно там написано, я забув»
const user = createUser({name: 'Volodymyr', role: 'user'});
if (user.getRole() === 'user') {
// do something
}
Хоча я більш ніж впевнений, що всі знають про magic strings, все ж таки поясню. Магічні рядки — це strings (numbers, booleans тощо), які зустрічаються більш ніж в одному місці та не винесені в одну, єдину змінну (константу/поле enum). Це не тільки зробить процес розробки набагато зручнішими, — та як не прийдеться, за потреби, шукати всі місця де вони зустрічаються, щоб змінити, але й використання змінної дає розуміння всім навколо, що ж це за значення в ній зберігається.
const USER_ROLE = 'user';
const user = createUser({name: 'Volodymyr', role: USER_ROLE});
if (user.getRole() === USER_ROLE) {
// do something
}
«The sky is the limit»
Хоча ті пункти, які я перерахував — це всього лишень 1% від всіх які, для розробника будь-якого рівня, було б доцільно розглянути, проте, найголовніший пункт — це цікавитись, слухати людей яких ви вважаєте авторитетами у цій темі і розвиватися. Завжди.
14 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів