Программирование
Полезный фреймворк для именования ваших классов, функций и переменных
«В компьютерном программировании соглашение об именах — набор правил для выбора последовательности символов, которая будет использоваться для идентификаторов, которые обозначают переменные, типы, функции и другие объекты в исходном коде и документации». Википедия
Называть вещи сложно!
В этой статье мы попытаемся сосредоточиться на методе именования A/HC/LC, который может улучшить читаемость кода.
Хотя эти правила можно применить к любому языку программирования, мы будем использовать JavaScript, чтобы проиллюстрировать их на практике.
Что такое (P)A/HC/LC?
Эта практика предлагает использовать следующий шаблон для наименования.
prefix? + action (A) + high context (HC) + low context? (LC)
Что такое префикс (Prefix)?
Префикс улучшает значение функции.
is
Описывает характеристику или состояние текущего контекста (обычно логическое).
const color = 'blue' const isBlue = (color === 'blue') // characteristic const isPresent = true // state if (isBlue && isPresent) { console.log('Blue is present!') }
has
Описывает, имеет ли текущий контекст определенное значение или состояние (обычно логическое).
/* Bad */ const isProductsExist = (productsCount > 0) const areProductsPresent = (productsCount > 0) /* Good */ const hasProducts = (productsCount > 0)
should
Отражает положительное условное выражение (обычно логическое) в сочетании с определенным действием.
function shouldUpdateUrl(url, expectedUrl) { return (url !== expectedUrl) }
Действия (Action) — это суть функции
Действия — это глагольная часть имени вашей функции. Они являются наиболее важной частью описания того, что делает функция.
get
Немедленный доступ к данным (т.е. быстрый метод получения внутренних данных).
function getFruitsCount() { return this.fruits.length; }
set
Декларативно устанавливает переменную со значением A в значение B.
const fruits = 0function setFruits(nextFruits) { fruits = nextFruits } setFruits(5) console.log(fruits) // 5
reset
Устанавливает переменную обратно в ее начальное значение или состояние.
const initialFruits = 5 const fruits = initialFruits setFruits(10) console.log(fruits) // 10 function resetFruits() { fruits = initialFruits } resetFruits() console.log(fruits) // 5
fetch
Запрашивает данные, на что требуется время (например, асинхронный запрос).
function fetchPosts(postCount) { return fetch('https://api.dev/posts', {...}) }
remove
Что-то откуда-то убирает.
Например, если у вас есть коллекция фильтров на странице поиска, удаление одного из них из коллекции — это removeFilter, а не deleteFilter (и это то, как вы, естественно, произносите это по-английски):
function removeFilter(filterName, filters) { return filters.filter(name => name !== filterName) } const selectedFilters = ['price', 'availability', 'size'] removeFilter('price', selectedFilters)
delete
Полностью стирает что-то.
Представьте, что вы редактор контента, и у вас есть печально известный пост, от которого вы хотите избавиться. После того, как вы нажали кнопку удаления публикации, CMS выполнила действие deletePost, а не removePost.
function deletePost(id) { return database.find({ id }).delete() }
compose
Создает новые данные из существующих данных. В основном это применимо к строкам, объектам или функциям.
function composePageUrl(pageName, pageId) { return `${pageName.toLowerCase()}-${pageId}` }
handle
Обрабатывает действие. Часто используется при именовании метода обратного вызова.
function handleLinkClick() { console.log('Clicked a link!') } link.addEventListener('click', handleLinkClick)
Наконец, Контекст (Context)
Контекст — это область, в которой работает функция.
Функция часто — это действие над чем-то. Важно указать, каков его рабочий домен или, по крайней мере, ожидаемый тип данных.
/* A pure function operating with primitives */ function filter(predicate, list) { return list.filter(predicate) } /* Function operating exactly on posts */ function getRecentPosts(posts) { return filter(posts, (post) => post.date === Date.now()) } /*Some language-specific assumptions may allow to omit the context. For example, in JavaScript it is common that filter operates on Array. Adding explicit filterArray would be unnecessary.*/
В итоге
5 рекомендации по именованию переменных
В этом разделе мы попытаемся сосредоточиться на некоторых правилах и протоколе именования переменных, которые улучшат читаемость кода.
1. S-I-D
Имя должно быть Кратким, Интуитивно понятным и Описательным (Short, Intuitive and Descriptive).
/* Bad */ const a = 5 // "a" could mean anything const isPaginatable = (postsCount > 10) // "Paginatable" sounds extremely unnatural const shouldPaginatize = (postsCount > 10) // Made up verbs are so much fun!
Лучше:
/* Good */ const postsCount = 5 const hasPagination = (postsCount > 10) const shouldDisplayPagination = (postsCount > 10) // alternatively
2. Избегайте сокращений
Не используйте сокращений. Они только ухудшают читаемость кода. Найти короткое описательное имя может быть сложно, но сокращение — не оправдание для того, чтобы этого не сделать. Например:
/* Bad */ const onItmClk = () => {} /* Good */ const onItemClick = () => {}
3. Избегайте дублирования контекста
Всегда удаляйте контекст из имени, если это не ухудшает его читабельность.
class MenuItem { /* Method name duplicates the context (which is "MenuItem") */ handleMenuItemClick = (event) => { ... } /* Reads nicely as `MenuItem.handleClick()` */ handleClick = (event) => { ... } }
4. Отражайте ожидаемый результат
/* Bad */ const isEnabled = (itemsCount > 3) return <Button disabled={!isEnabled} /> /* Good */ const isDisabled = (itemsCount <= 3) return <Button disabled={isDisabled} />
5. Учитывайте единственное/множественное число
Как и префикс, имена переменных могут быть единственными или множественными, в зависимости от того, содержат ли они одно значение или несколько.
/* Bad */ const friends = 'Bob'; const friend = ['Bob', 'Tony', 'Tanya']; /* Good */ const friend = 'Bob'; const friends = ['Bob', 'Tony', 'Tanya'];
6. Используйте осмысленные и произносимые имена переменных
const yyyymmdstr = moment().format("YYYY/MM/DD"); // simply awful // Instead const currentDate = moment().format("YYYY/MM/DD");
Эта статья была вдохновлено этим репозиторием на GitHub. Хорошего кода!