🅰 Именование

Дать имя и не остаться в дураках

Пожалуй самое сложное в программировании - это доносить свои мысли через код до других программистов. Код должен быть читаемый подобно книге, сказал Роберт Мартин в своей книге "Чистый код". Многие понимают это прямо и это ошибка. На самом деле это недостижимый идеал. К нему нужно стремиться, но его никогда не достигнуть.

Предлагаю пойти "от противного" и посмотреть для начала как не нужно делать.

Если бы мы знали что это такое, но мы не знаем что это такое

Почему у разработчиков тяга к бесполезным префиксам и постфиксам, а так же к сильно обобщенным именованиям - не известно.

Давайте рассмотрим добавление префикса/постфикса:

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. Об этом мы поговорим чуть ниже.