Инженерная практика: дать функциям «хорошее» имя

задняя часть

Еще в 2013 году иностранные программисты провели интересное голосование (см. оригинальную ссылку: "Программист: Как вы думаете, что самое сложное?》), в этом голосовании программисты должны выбрать из следующих вариантов то, что, по их мнению, сложнее всего делать на работе:

  • Сделать дизайн проекта
  • Пишите тестовые случаи
  • Пишите проектную документацию
  • объяснить другим, что мы делаем
  • Достичь функции, с которой вы не согласны
  • Вносить изменения на основе кода, написанного другими
  • общаться с людьми
  • Назовите функции и переменные
  • При оценке рабочей нагрузки

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

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

A. Стиль общего функции

2. Высшее царство функции по имени

3. Лучшие практики именования функций

Прошу простить меня, если есть какие-то неточности, и приветствую критику и исправления.

Просим уважать достижения труда автора, при перепечатке указывать ссылку на оригинал:

HTTPS://woowoo.cn blog.com/dolphin0520/fear/10567879.HTML

I. Частая функция с именем style

В настоящее время существует два основных стиля именования функций: CamelCase и Pascal.

  • Именование в верблюжьем регистре: когда несколько слов образуют имя, первое слово пишется строчными буквами, а следующие слова пишутся с большой буквы, например:
public void setUserName(String userName);
  • Именование в Паскале: когда несколько слов образуют имя, первая буква каждого слова пишется с заглавной буквы;
public void SetUserName(String userName);

Оба стиля именования приемлемы, но убедитесь, что для команды или проекта вам необходимо принять соглашение в соответствии с рекомендуемым методом именования самого языка. Например, в java обычно используются имена в регистре верблюдов, а в C# используется имена в стиле Pascal.

2. Высший уровень именования функций

Мы обычно говорим: боевые искусства мира, только быстро не может быть нарушена. Итак, каково современное состояние именования функций? Я так думаю:лицом к лицу, как следует из названия, заключается в том, чтобы увидеть имя функции, чтобы узнать, что она делает.

Например, функция выше:

public void setUserName(String userName);

Но следующее имя функции не является хорошим именем:

public String addCharacter(String originString, char ch);

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

И следующие имена намного лучше, чем приведенные выше:

public String appendCharacter(String originString, char ch);     // 追加到末尾
public String insertCharacter(String originString, char ch, int insertPosition); // 插入指定位置

3. Лучшие практики именования функций

1) Основы 1: выбор глагола должен быть точным

В общем, глаголы определяют, какое «действие» должна предпринять функция. Хорошие глаголы, имя функции было успешным в 80% случаев.

Список часто используемых глаголов:

категория

слово

добавить/вставить/создать/инициализировать/загрузить

добавить, добавить, вставить, создать, инициализировать, загрузить

удалить/уничтожить

удалять, удалять, уничтожать, сбрасывать

открыть/запустить/запустить

открыть, начать

закрыть/стоп

близко, стоп

получить/прочитать/найти/запросить

получить, получить, приобрести, прочитать, искать, найти, запросить

установить/сбросить/поставить/записать/освободить/обновить

установить, сбросить, положить, записать, отпустить, обновить

отправить/отправить

Отправить, толчок

Получить / вытащить

получать, тянуть

Отправить/Вывести/Отменить

Отправить Отменить

собирать/собирать/выбирать/выбирать

собирать, выбирать, выбирать

Извлечь/разобрать

подпрограмма, извлечение, разбор

кодировать декодировать

кодировать, декодировать

заполнение/упаковка/сжатие

заполнять, упаковывать, сжимать

Очистить/распаковать/разархивировать

очистить, очистить, распаковать, распаковать

Увеличение уменьшение

увеличить, уменьшить, уменьшить

Разделение/сращивание

разделить, присоединиться, объединить

Фильтровать/Проверить/Обнаружить

фильтровать, действительно, проверить

2) Основы 2: Используйте доменную лексику для существительных

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

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

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

Список общих терминов:

категория

слово

вместимость/размер/длина

мощность, размер, длина

Примеры / контекст

пример, контекст

настроить

конфиг, настройки

голова/передний/предыдущий/первый

заголовок, передний, предыдущий, первый

хвост/позади/следующий/последний

хвост, назад, следующий, последний

Интервал/площадь/часть/диапазон/масштаб

диапазон, интервал, область, площадь, сечение, размах, масштаб

кеш/буфер/сеанс

кеш, буфер, сеанс

местный/местный/глобальный

локальный, глобальный

Члены / элементы

член, элемент

меню/список

меню, список

исходная цель

источник, пункт назначения, цель

3) Основа 3: Самое табуированное название функции — «недостойное имени».

Большинство TABOO для имени функций «недостойны имени». Например, если есть класс кэша, в нем есть функция, чтобы определить, истек ли ключ:

public boolean isExpired(String key) {
        // 当前时间戳
        long curTimestamp = DateUtils.nowUnixTime();
        // 获取key的存入时间戳
        long storeTimestamp = getStoreTimestamp(key);
       
        if (curTimestamp - storeTimestamp > MAX_EXPIRE_SECONDS) {
            // 注意这个地方的delete是个隐藏逻辑
            delete(key);
            return true;
        }
        return false;
 }

Вышеупомянутая функция буквально означает, что срок действия ключа истек, но! !Это на самом деле скрывает в функции особую логику: удалить ключ, если срок его действия истек.Это типичный «недостойный имени», который является самым табуированным и оставит «гигантскую яму» для последующих разработчиков.

Есть два способа оптимизировать этот код:

  • Способ 1: удалить скрытую логику
public boolean isExpired(String key) {
        // 当前时间戳
        long curTimestamp = DateUtils.nowUnixTime();
        // 获取key的存入时间戳
        long storeTimestamp = getStoreTimestamp(key);
       
        if (curTimestamp - storeTimestamp > MAX_EXPIRE_SECONDS) {
            return true;
        }
        return false;
 }
  • Способ 2: изменить имя функции
public int deleteIfExpired(String key) {
        // 当前时间戳
        long curTimestamp = DateUtils.nowUnixTime();
        // 获取key的存入时间戳
        long storeTimestamp = getStoreTimestamp(key);
       
        if (curTimestamp - storeTimestamp > MAX_EXPIRE_SECONDS) {
            return delete(key);
        }
        return 0;
 }

4)Основы 4. Осторожно используйте предлог by в имени функции нескольких условий запроса

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

public List<Student> getByName(String name);

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

public List<Student> getByNameAndMobile(String name, String mobile);

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

public List<Student> getByNameAndMobileAndAge(String name, String mobile, int age);

Если вы назовете свои функции так, вы вот-вот откроете дверь в кошмар.

Обычно хорошей практикой является:

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

public Student getByStudentId(long studentId);
  • Если он запрашивается по другим атрибутам, и в будущем будет возможность нескольких комбинированных запросов, рекомендуется инкапсулировать, например:

public List<Student> getStudents(StudentSearchParam searchParam);

Наконец, я предлагаю в процессе написания кода не бояться тратить время на именование функций. Хорошее именование функций значительно снизит стоимость рефакторинга вашего кода на более позднем этапе, и постарайтесь сделать именование функций " буквальный "~