Вы когда-нибудь пытались назвать свои переменные или функции в своем коде? Я знаю, что у меня есть! Раньше я тратил слишком много времени, пытаясь придумать идеальное имя, только чтобы потом понять, что оно было не совсем правильным.

Как программист, я на горьком опыте усвоил, что присвоение имен переменным и функциям — одна из самых важных и сложных задач в разработке программного обеспечения. Имена, которые мы выбираем, могут повлиять на удобочитаемость, ремонтопригодность и даже функциональность нашего кода.

«Хороший код сам по себе является лучшей документацией. Собираясь добавить комментарий, спросите себя: «Как я могу улучшить код, чтобы этот комментарий не понадобился?» — Стив МакКоннелл.

Именование сложно

Именование переменных и функций может быть одной из самых сложных частей кодирования. Имя должно быть четким и кратким, а также предоставлять полезный контекст о назначении переменной или функции. Это прекрасный баланс, и требуется время, чтобы развить навык именования.

«Называть вещи сложно. Если вы не можете придумать хорошее имя, обычно это признак того, что вы не совсем понимаете, что пытаетесь назвать».

— Уилл Ларсон, автор книги «Элегантная головоломка: системы инженерного менеджмента».

Хорошие имена рассказывают историю

Хорошее имя переменной или функции должно рассказывать историю о ее назначении и функциональности. Когда кто-то читает ваш код, он должен понять, что делает переменная или функция, просто взглянув на ее имя.

«Длинное описательное имя лучше, чем короткое загадочное имя. Длинное описательное имя лучше длинного описательного комментария». - Роберт С. Мартин

type BlogPost struct {
    Title       string
    Body        string
    Author      string
    PublishDate time.Time
}

В этом примере имена переменных рассказывают историю о назначении и функциональности структуры BlogPost. Поле Title представляет заголовок сообщения в блоге, поле Body представляет основную часть сообщения в блоге, поле Author представляет автора сообщения в блоге, а поле PublishDate представляет дату публикации сообщения в блоге.

Благодаря использованию описательных имен переменных код становится более читабельным и самодокументируемым. Другой разработчик, читающий этот код, может понять назначение структуры BlogPost, просто взглянув на имена переменных, не нуждаясь в дополнительных комментариях или документации.

Однобуквенные имена — это плохо; В общем

В большинстве случаев следует избегать однобуквенных имен переменных, поскольку они не обеспечивают достаточного контекста для понимания назначения переменной. Также может возникнуть путаница, если одна и та же буква используется для разных переменных в разных частях кода.

«Сделайте имена переменных описательными и осмысленными. Если имя переменной не описывает ее назначения, это плохое имя». — Джоэл Спольски

Конечно, есть исключения из общего правила, согласно которому следует избегать однобуквенных имен переменных. Одним из примеров является использование «i» для индекса в цикле, что стало общепринятым во многих языках программирования. В этом случае «i» является общепризнанным сокращением для «индекса», и использование более длинного имени переменной не добавило бы никакого дополнительного контекста или ясности коду. Однако важно помнить об использовании однобуквенных имен переменных в других сценариях, где они могут вызвать путаницу или затруднить чтение и обслуживание кода.

Избегайте использования типа переменной в имени переменной

Использование типа переменной в имени переменной может быть излишним и ненужным, поскольку в объявлении переменной уже должен быть указан ее тип. Это также может ограничить гибкость переменной в будущем, если ее тип нужно будет изменить.

«Программы должны быть написаны для того, чтобы люди их читали, и лишь случайно для того, чтобы машины выполняли их». - Гарольд Абельсон и Джеральд Джей Сассман

Использование структуры данных в имени переменной, такой как «список» или «массив», может быть избыточным и ненужным, поскольку в объявлении переменной уже должен быть указан ее тип. Кроме того, это может ограничить гибкость переменной, если ее тип потребуется изменить в будущем. Поэтому, как правило, лучше использовать более описательное и осмысленное имя, отражающее назначение переменной в контексте кода.

// bad names
var intList []int
var strList []string

// good names
var numbers []int
var names []string

Хорошие имена должны быть близки к тому, как компании используют имена

Важно использовать имена переменных и функций, близкие к тому, как бизнес-пользователи относятся к концепциям, моделируемым в коде. Это может облегчить понимание кода нетехническими заинтересованными сторонами и предоставление отзывов. Код — это инструмент для общения, и использование одних и тех же имен в разных подразделениях организации способствует лучшему общению.

«Самое важное свойство программы заключается в том, выполняет ли она намерение пользователя». - МАШИНА. Хор

Хорошим именам нужно меньше комментариев

Хорошо названная переменная или функция требует меньше комментариев для объяснения ее назначения, поскольку само имя предоставляет полезную информацию о коде. Это может сделать код более удобным для чтения и обслуживания с течением времени. Поэтому, когда вы чувствуете необходимость добавить комментарий к идентификатору, чтобы объяснить, что это такое или что он делает, пришло время переосмыслить, подходит ли это имя. Комментарий в большинстве случаев должен использоваться для того, почему, а не для чего.

«Если вам нужен комментарий, чтобы объяснить, что делает фрагмент кода, значит, этот код недостаточно хорош». — Мартин Фаулер

Вот несколько примеров хороших имен функций в реальном мире Go:

  1. ParseTime — функция, которая берет строку, представляющую время, и преобразует ее в значение time.Time.
  2. AddOrUpdateUser — функция, которая добавляет нового пользователя в базу данных или обновляет существующего пользователя, если он уже существует.
  3. FindNearestNeighbors — функция, которая находит ближайших соседей заданной точки данных в наборе многомерных данных.
  4. CalculateDistance - функция, вычисляющая расстояние между двумя точками в заданной системе координат.
  5. BuildTree — функция, которая строит структуру данных для эффективного поиска и извлечения данных.

В каждом из этих примеров имя функции четко и лаконично описывает, что делает функция, облегчая другим разработчикам понимание и использование кода.

Последовательность является ключевым

Последовательность в соглашениях об именах важна для того, чтобы сделать код более читабельным и удобным в сопровождении. Если переменные и функции названы последовательно, становится легче выявлять шаблоны и понимать цель кода.

«Постоянство — это не просто добродетель; это обязательство. Без последовательности код становится нечитаемым, неработоспособным и неподдерживаемым». - Роберт С. Мартин

Используйте глаголы для имен функций

При именовании функций важно думать о назначении функции и выполняемом ею действии. Глаголы более ориентированы на действие и дают понять читателю, что делает функция. Кроме того, использование глаголов в качестве имен функций способствует согласованности и ясности кодовой базы.

Предположим, у нас есть функция, которая принимает массив целых чисел и возвращает сумму всех четных чисел в массиве. Плохим названием для этой функции было бы «EvenSumArray», что не очень ясно в отношении того, что делает функция. Лучшее имя было бы «SumEvenNumbers» или «GetEvenSum», что указывает на то, что функция вычисляет сумму четных чисел в массиве.

«Имена функций должны быть глаголами, а не существительными». - Роберт С. Мартин

Вот пример того, как можно написать функцию с хорошим именем:

func SumEvenNumbers(numbers []int) int {
    sum := 0
    for _, num := range numbers {
        if num % 2 == 0 {
            sum += num
        }
    }
    return sum
}

Как видите, название функции указывает на то, что она делает. Он принимает массив целых чисел и вычисляет сумму четных чисел в массиве.

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

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

Например, функции Go, возвращающие логическое значение, указывающее, является ли определенное условие истинным или ложным, могут быть названы прилагательным, описывающим проверяемое условие. Например, функция, проверяющая, является ли данный срез пустым, может называться isEmpty. Эта функция названа в честь прилагательного, а не глагола, потому что она описывает состояние проверяемого среза.

В других случаях функции Go могут быть названы в честь существительного, если они являются фабричными функциями, которые создают и возвращают объекты типа этого существительного. Например, пакет http в Go имеет функцию NewServeMux, которая создает и возвращает новый объект ServeMux. Функция названа в честь существительного «ServeMux», а не глагола, потому что она создает экземпляр этого объекта.

В конечном счете, цель при именовании функций Go состоит в том, чтобы выбрать имя, которое точно отражает то, что делает функция, и которое другим будет легко понять и использовать в собственном коде. Независимо от того, является ли имя функции глаголом, прилагательным или существительным, оно должно быть четким и соответствовать соглашениям об именах языка и проекта.