🅰 Именование
Дать имя и не остаться в дураках
Пожалуй самое сложное в программировании - это доносить свои мысли через код до других программистов. Код должен быть читаемый подобно книге, сказал Роберт Мартин в своей книге "Чистый код". Многие понимают это прямо и это ошибка. На самом деле это недостижимый идеал. К нему нужно стремиться, но его никогда не достигнуть.
Предлагаю пойти "от противного" и посмотреть для начала как не нужно делать.
Если бы мы знали что это такое, но мы не знаем что это такое
Почему у разработчиков тяга к бесполезным префиксам и постфиксам, а так же к сильно обобщенным именованиям - не известно.
Давайте рассмотрим добавление префикса/постфикса:
const userData: User = {
id: number
name: string
}
Когда я спрашиваю, что означает Data
на конце, к сожалению в лучшем случае я получают ответ "данные". Если я получаю такой ответ, то задаю вопрос, почему у него на каждой переменной не висит префикс/постфикс data
. Обычно люди понимают, что это бесполезная штука, мне каждый раз приходится это напоминать, ведь привычка очень долго выкорчёвывается. Тоже самое касается и info
.
Рассмотрим следующий пример:
async function foo(value: User) {
...
const object = convert(value)
...
const data = await request(object.query)
if (data.error) {
return setError(...)
}
...
setData(data, object.bar)
}
Когда я читаю такой код, я сразу представляю, как такой человек рассказывает про свои действия в таком ключе:
Вчера я с людьми, сел в транспортное средство и поехал на место. Место было красивое, мы решили удовлетворить естественную потребность. Взяли мебель и пододвинули к мебели, человек принес нам углеводы, жиры и белки. Мы их перенесли из посуды в желудок.
Так же отмечу что я Так никто не общается, все говорят "мы с друзьями сели в машину", "решили поесть", "пододвинули стулья и сели за стол", "официант принес нам еду" и т.д. Обычно человек в своей речи использует слова, которые конкретизируют то, что они хотят сказать.
Перепишем функцию избавившись от неверного именования:
async function foo(user: User) {
...
const { query, bar } = convert(user)
...
const response = await request(query)
if (response.error) {
return setError(...)
}
...
setResponse(response, bar)
}
Данный пример содержит условности, но отражает суть. Не нужно обобщать, если вы работаете над конкретными сущностями.
Обобщения нужны в том случае, если вы не знаете с чем конкретным будет работать ваш код. Например есть метод map
у массива. Мы не знаем какие данные конкретно будет использовать пользователей нашей функции. Давайте ее напишем.
function map<A, B>(array: A[], ab: (item: A) => B): B[] {
const result = [] as B[];
for (let index = 0; index < array.length; index++) {
result.push(ab(array[index]));
}
return result;
}
Рассмотрим имена и начнем с аргументов. array
- это просто массив, мы не знаем, что это за массив, мы можем работать с любым массивом, единственное ограничение и конкретика здесь, то что это должен быть массив. ab
- это функция которая преобразует a -> b
. Потому тут не используется слово "callback", которое может означать абсолютно любую функцию. У данной функции есть прямая задача и здесь отражается суть. Можно назвать более полно - convertAToB
, transformAToB
и т.д. Я выбрал более короткое имя, оно имеет стандарт в мире функционального программирования. Так как это чистая функция, с именем map
- которое пришло к нам их этого мира, я решил использовать их стандарты.
Далее имя result
- оно нам говорит о том, что это результат функции. Так как у нее довольно четкие границы и больше, к тому же данная переменная прибита к for
- человек сразу понимает, что это и зачем. Так как нет информации, какие элементы будут в результате, так и остается result
.
Я не сокращаю index
до i
. Об этом мы поговорим чуть ниже.