Манифест Чистого Программиста или краткий конспект книги «Чистый Код» Роберта Мартина

    Данная статья является конспектом книги "Чистый Код" Роберта Мартина и моим пониманием того, каким Чистый Код должен быть. Тут нет разделов о тестировании, TDD, о том какая должна быть архитектура и т.д. Здесь все только о том, каким должен быть Чистый Код.





    Да, возможно, тема Чистого Кода уже заезженна, но тем не менее еще не все с ним знакомы и, тем более, я не встретил аналогов контента, который содержится в моей статье.


    Общее


    Нет истинного пути и решения. Есть тот, который лучше всего подходит для решения конкретной задачи.


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


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


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


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


    • Какие кейсы могут быть у задачи?
    • Все ли я учел?
    • Что может пойти не так?
    • Что можно объединить?
    • Есть ли похожий функционал?
    • Что тут лишнее?
    • Как сделать проще?
    • Как сделать читабельнее?
    • Как сделать понятнее?

    Чистый Код


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


    Под сущностью понимается — интерфейс, класс, метод, переменная, объект и т.д.


    • Чистый код простой, выразительный и направлен на конкретную задачу.
    • Чистый код читается легко, как проза. Если это не так, то его стоит рефакторить.
    • Чистый код легко изменять. Он не должен быть жестко завязан на куче сущностей. Любую сущность можно легко изменить.
    • Чистый код намного лучше проходит ревью. Если ревью проходит с огромным количеством комментариев, то он не чистый и его надо рефакторить.
    • Чистый код всегда выглядит так, словно над ним очень долго трудились. Какие бы пути для его улучшения ты не искал, ты все равно придешь к тому, что этот код лучший. Соответственно, чистый код — продуманный до всех мелочей.
    • Правило бойскаута: Оставь место стоянки чище, чем оно было до тебя. Это легко перекладывается и на программирование. Видишь грязный код? Сделай его чище, пока решаешь свою задачу. Не стоит увлекаться этим и если грязный код очень грязный, то стоит выделить отдельную задачу и время для его очистки.
    • Не бойся делать изменений. Если ты хочешь их сделать, то значит у тебя есть на то причины, а значит ты сделаешь код лучше и чище. Тем более тесты покажут нет ли ошибок в твоем коде (при условии, что они вообще есть).
    • Любая сущность должна отвечать за один функционал и только за него. И она должна выполнять его хорошо. Single Responsibility.
    • Если сущность отвечает сразу за два и более действий, то её функционал нужно разделять.
    • Код должен читаться сверху вниз.
    • В хорошей и грамотной архитектуре внесение изменений обходится без значительных затрат и усилий.
    • Удаляй мертвый код. Мертвый код это код, который не будет вызван ни при каких условиях или код, который нигде не используется.

    Наименования и разделения


    • Используй понятные и удобнопроизносимые имена для любых сущностей. Они должны описывать почему эта сущность существует, что она делает и как используется.
    • Не бойся тратить время на выбор лучшего и понятного имени. Ты выиграешь в будущем при работе или чтении этого кода.
    • Если название сущности не соответствует еë функционалу или по названию не понятно, что сущность делает, то еë надо переименовать в самое понятное название. Если этого сделать невозможно, то значит с еë функционалом что-то не так и еë надо рефакторить.
    • Сущность, которая имеет в названии "And", "With" — нарушает Single Responsibility. Функционал такой сущности стоит разделять. Но этим правилом стоит иногда пренебрегать.
    • Непонятные тексты, строки стоит выносить в переменные и давать им понятные названия.
    • Названия методов должны содержать глагол, который описывает, что этот метод делает и ключевое слово с которым работает данный метод. Если в названии метода нет глагола, то эта сущность не должна быть методом или ему нужно дать правильное название.
    • Нужно избегать одинаковых наименований для двух разных целей.
    • Если сущность имеет схожее с другой сущностью название, то скорее всего их функционал очень сильно похож и их нужно объединить? Если нет, то их названия нужно менять так, чтобы они не были похожими.
    • Если ты мысленно переименовываешь сущность, когда читаешь код, чтобы тебе было понятнее понимать её функционал, то переименуй её в это мысленное название.
    • Выбери одно слово для одной концепции. Сложно будет понимать функционал, когда у тебя есть fetch, retrieve и get в названиях. Пусть лучше везде будет get.
    • Длинное и понятное имя лучше, чем короткое, но непонятное.

    Функции


    • Функции должны быть короткими и компактными.
    • Функции должны быть очень короткими и очень компактными.
    • Приблизительный максимум 20 строк и 150 символов в одной строке, если не влезает, то нужно разделять.
    • Функция должна выполнять только одну операцию.
      • Она должна выполнять её хорошо и ничего другого она делать не должна.
      • Если функция выполняет только те действия, которые находятся на одном уровне абстракции, то функция выполняет одну операцию.
      • Чтобы определить выполняет ли функция более одной операции, попробуй извлечь из нее другую функцию, которая не будет являться простой переформулировкой реализации.
    • Любые условные операторы с длинными выборами через switch-case, if-else должны разделяться или объединяться без дублирования, возможно на классы с реализациями, а выбор реализации передать базовому классу, фабрике или еще кому-то.
    • If, else, while и т.д. должны содержать вызов одной функции. Так будет читабельнее, понятнее и проще.
    • Идеальное количество входных аргументов для функции = 0. Если входных аргументов больше трех, то стоит задуматься каким образом лучше от них избавиться, например, создать класс для этих аргументов.
    • Чем больше входных аргументов, тем тяжелее понимается функция.
    • Функция в которую передается аргумент-флаг, от которого зависит работа функции говорит о том, что функция выполняет более одной операции. Такие функции следует разбить на две и вызывать их уровнем выше.
    • Функция, которая изменяет входной аргумент, должна отдавать ссылку на измененный объект, а не просто изменять без возврата. String transform(String text)
    • Если функция, должна изменять входной аргумент, то пусть она изменяет состояние своего объекта-владельца.
    • Если входной аргумент функции не должен меняться (и используется дальше в коде), то следует скопировать значение аргумента и внутри функции работать с копией.
    • Вместо return null лучше использовать пустой объект — Collection.empty() или null-объект -EmptyObject().
    • Всегда старайся использовать нестатические функции. Если это невозможно, то используй статические.
    • Если есть код, который должен следовать один за другим, то передавай результаты первой функции во вторую, чтобы кто-нибудь не изменил последовательность вызовов.
    • Используй полиморфизм вместо if/else или switch/case или when.
    • Избегай отрицательных условий.

    Комментарии


    • Не используй комментарии, если ты можешь использовать функцию или переменную вместо этого.
    • Не комментируй плохой код — перепиши его. Не стоит объяснять, что происходит в плохом коде, лучше сделать его явным и понятным.
    • Комментарии можно использовать для передачи какой-то информации, предупреждения о последствиях, но не для объяснения того, как работает код.
    • Используй TODO и FIXME в тех случаях, когда нужно пометить, что код нуждается в доработке, но сейчас нет ресурсов на это.
    • Используй //region REGIONNAME //endregion REGIONNAME, а если используешь, то подумай можно ли разделить region на сущности.
    • Документируй код, который является сложным, но чистым.
    • Не оставляй старый закомментированный код. Ты можешь найти его в истории коммитов, если необходимо.
    • Комментарии должны быть краткими и понятными. В комментариях с информацией не должно быть много информации. Все должно быть кратко и по делу.

    Форматирование и правила


    • Соблюдай codestyle, принятый на проекте.
    • Соблюдай правила, принятые в команде.
    • При соблюдении форматирования и codestyle код будет читаться проще и лучше. Ведь не зря книгу отдают на редакцию, перед тем, как её издавать.
    • Нужно иметь автоматические средства, которые будут форматировать код за тебя.
    • Файл с исходным кодом должен быть как газетная статья. Есть заголовок, краткое описание в виде параметров и содержание в виде функций. Если это не так, то стоит изменить форматирование.
    • Сущности, связанные друг с другом, должны находиться рядом, например, в одном package, чтобы было проще навигировать по коду.
    • Переменные(поля) класса должны находиться вверху класса.
    • Переменные методов должны находиться ближе к своему месту использования.
    • Функции должны находиться в порядке вызова. Если одна вызывает другую, то вызывающая функция должна находиться над вызываемой. C другой стороны, приватные функции более низкого уровня могут находиться внизу файла и не мешать пониманию кода высокого уровня. Но я предпочитаю первый способ.

    Объекты и структуры данных


    • Ты должен работать с абстракциями, чтобы реализацию можно было легко изменить.
    • Ты должен работать с абстракциями, потому что клиент, использующий функционал, не должен знать о деталях реализации, он должен знать какую реализацию в каком случае использовать.
    • Ты должен предоставлять API, с которым стоит работать и скрывать детали реализации, структуру. Так будет проще работать с такими сущностями и добавлять новые виды поведений, функционала и реализаций.
    • DTO — Data Transfer Object. Класс, который содержит только данные и никакого функционала. Нужен для того, чтобы передавать какие-то данные. Объект такого класса должен быть неизменяемым.

    Классы


    • Классы должны быть компактными.
    • Классы должны быть еще компактнее.
    • Имя класса должно описывать его ответственности. Отсюда можно и вычислить размер класса.
    • Функционал класса должен четко соответствовать и вписываться в название класса.
    • Разделяй связанность на маленькие классы. Жесткой и обильной связанности не должно быть — это усложняет поддержку и развитие проекта.
    • Помни о Single Responsibility. Сущность должна иметь одну и только одну причину для изменения.
    • Соблюдай инкапсуляцию. Ослабление инкапсуляции всегда должно быть последней мерой.
    • Обычно мы объявляем переменные и вспомогательные функции приватными, но иногда их нужно объявлять protected и иметь возможность обратиться к ней из теста.
    • Если группа функций относится к определенному функционалу, то эту группу функций можно и нужно выделить в отдельный класс и использовать его экземпляр.

    Обработка ошибок


    • Используй Exceptions вместо возвращения кодов ошибок.
    • Обработка ошибок — это одна операция. Если в функции есть ключевое слово try, то после блоков catch/finally ничего другого в функции быть не должно.
    • Если у тебя есть enum, который перечисляет ошибки, то от него лучше избавиться и вместо него использовать исключения.
    • Используй unchecked exceptions, чтобы явно указать на место в котором есть проблемы. Такие ошибки не нужно отлавливать, вместо этого нужно написать код так, чтобы этой ошибки никогда не было.
    • Передавай достаточное количество информации вместе с выбросом исключения, чтобы потом пользователи твоего кода могли понять, что же действительно произошло.
    • Вместо условных операторов с обработкой ошибок лучше выбрасывать исключения и обрабатывать их.
    • Не передавай null куда-либо. Старайся этого максимально избежать.
    • Обработка ошибок — это отдельная задача и не относится к основной логике программы.

    Границы


    • Мы всегда используем какие-либо библиотеки, которые чаще всего дают нам слишком широкий, слишком маленький функционал или конфликтуют с ожидаемым функционалом, что делает код грязнее в его конечном использовании. Избежать этого можно просто применив паттерны типа Decorator, Adapter, Facade или другие.
    • Бывают ситуации, когда тебе нужно работать с функционалом, который находится в разработке или пока что не адаптирован для использования в продакшен коде. В этом случае стоит представить чего ты ждешь от библиотеки/этого функционала и написать свой интерфейс или создать сущность с которыми ты будешь работать в своем проекте так, как тебе нужно. Когда библиотека доделается и станет стабильной, ты адаптируешь её под свои готовые структуры и использовать уже готовый функционал.

    Послесловие


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

    Поделиться публикацией
    Комментарии 48
      –12
      Откуда стойкое обращение на Ты :-? Это вроде не men's health & K
        +4
        Это лишь способ повествования) Каждый, кто читает что-либо, никогда не обращается к себе на вы)
        +2
        Достойная выжимка, ничего нового, но конспект отличный. Можно распечатывать и класть на рабочий стол
          +1
          Спасибо) Собственно, с этой целью и создавался данный материал) Чтобы под рукой всегда была краткая памятка того, как стоит писать код)
            +2
            Спасибо вам за такой труд.
            Часто не хватает таких конспектов по книгам. Самому составлять очень лень(
          0
          Отличный труд! Но, мне кажется, лучше стараться делать функции чистыми и отказываться от модификации передаваемых аргументов. Если хочется изменить входной аргумент — пусть функция вернет модифицированную копию. Это не всегда возможно, но к этому стоит стремиться. Такой код проще читать и проще тестировать.
            0
            … а еще он отлично жрет процессорное время и память (реклама производителей железок)
              0
              Так там так и написано
              +4
              Не забудьте после каждого пункта поставить запятую и дописать: «but it depends...»
                0
                Используй TODO и FIXME.

                Крайне сомнительная рекомендация. Либо делай сразу, либо заводи задачу там, где она не потеряется. А вот уже ссылку на задачу можно добавить в TODO.
                  0
                  Я вот тоже не очень понимаю, зачем приниципиально оставлять TODO в коде, а не создавать задачу в трекере задач. Недавно только чистили код от TODO, которые лежали просто годами.
                    +1
                    А TODO и должно ссылаться на задачу. Например сегодня мы работаем с x86, но в будущем нам, возможно, потребуется поддержать ARM. Заводится задача по поддержке ARM'а и всё TODO ссылаются на неё.

                    Можно ли сразу поддержать ARM? Можно, но не нужно: полноценная поддержка усложнит разработку в 1.5-2 раза, а если вы оставите «мёртвый код» без тестов и/или пользователей, то обнаружите, что к моменту, когда он понадобится — код «протухнет». TODO «протухают» тоже, конечно, но худшее, что с ними может произойти — они станут непонятными и вы их выкините, а странный код, появившийся ради задачи, от которой, в итоге, отказались будет вам мешать долгие годы — так как без комментариев все будут его видеть, но никто не будет понимать — зачем он там.
                      0
                      Без этого вашего пояснения фраза
                      Используй TODO и FIXME.

                      вредна. Сегодня с утра один наш разработчик скинул в общий чат скриншот этой статьи с этой фразой. Тогда как у нас в компании всего месяц назад с моей подачи запретили оставлять в коде TODO без указания номера задачи.
                        0
                        Я расставляю TODO и fixme в коде, но логика в том, что ни один TODO и FIXME не попадает в релизный код, без указания на задачу. Т.е. пока я работаю над кодом, в нем может быть неограниченное количество TODO по разным причинам. Например, просто как напоминалка, что здесь пока что затычка и костыль, чтобы упростить разработку другой подсистемы (да, сильносвязанный код зло, но это не моя вина и рефакторинг не всегда возможен). Однако как только завершаются все таски и код отдается на тестирования, для всех оставшихся TODO нужно создать задачи и заменить на ссылки.
                      0
                      Ну, можно создать связку, которая переводит TODO сразу в трекер, для этого вроде уже существуют инструменты
                      0
                      Это призыв к использованию TODO и FIXME в тех случаях, когда нужно пометить, что код нуждается в доработке.
                        +2
                        Я часто использую TODO и FIXME, чтобы потом вернуться к месту на которое сейчас не является приоритетным. Проект настроен так, что не собирается если в коде где-то есть эти метки, что помогает не забыть о том, что хотел сделать и не сделал.
                          +1
                          В MS VS комбинация кнопок ctrl + w,t открывает окно со списком всех TODO в проекте. В других IDE наверное тоже есть что то подобное.
                          +2
                          Чтоб научиться писать хороший код — нужно много писать и читать код, периодически возвращаясь к доработке уже написанного. Без такой практики этот список не поможет, а вот качестве дополнения будет очень полезен.
                            0
                            >>Обработка ошибок — это одна операция. Если в функции есть ключевое слово try, то после >>блоков catch/finally ничего другого в функции быть не должно.
                            Предполагает вынос блока try в отдельную функцию. Имеет ли смысл выносить в отдельную функцию если внутри блока одна строчка
                              0

                              Автор утверждает, что имеет, насколько помню. Я с этим согласен. Есть метод, который работу работает. Есть тот, который ошибки ловит. И второй не разобран на части первым. И вообще это разные задачи, зачем их перемешивать?


                              Привыкнуть только никак не могу. Среда разработки и язык не располагают к хоть сколько нибудь быстрому и / или удобному рефакторингу. В Джаву хочу, на Идею… И выделять методы, выделять методы...

                              +3
                              Идеальное количество входных аргументов для функции = 0. Если входных аргументов больше трех, то стоит задуматься каким образом лучше от них избавиться, например, создать класс для этих аргументов.

                              По мне так наоборот. Не стоит плодить классы с методами без аргументов, в случае нужды будет сложнее понять какие конкретно данные метод берет, на какие другие методы эти данные повлияют, и сложно будет метод переиспользовать.
                              Нужно стремиться к чистым функциям. Вот вход, вот выход, все сразу понятно из заголовка. Если забирает сразу много данных — сделай интерфейс.
                                +2
                                +1
                                Идеальное — это 1. Что-то вошло — что-то вышло. Прямолинейный поток выполнения, композиция, лёгкость переиспользования. Когда у функции нет аргументов, это значит, что она берёт входную информацию из окружения, а значит имеет побочный эффект. Такую архитектуру нельзя называть «чистой».
                                  0

                                  this для методов — это не окружение, а один из аргументов.

                                    0

                                    Да, конечно.


                                    int doSomething() {
                                      this.data = 42;
                                      return this.data;
                                    }

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

                                  0

                                  А почему методы не могут быть чистыми?

                                    0

                                    Могут, это приветствуется, и вполне заметно улучшает поддерживаемость кода.
                                    Но представим, что все методы чистые. Это значит, что их работа не зависит от состояния инстанса класса, и тогда возникает вопрос: "Зачем эти все методы содержатся в этом классе?"


                                    И есть только один разумный ответ: класс просто группирует эти методы (которые уже просто функции), но если язык позволяет организовывать модули просто с внешними функциями (например, Kotlin, Scala, Rust), то вполне естественно организовать их так.


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

                                      +2
                                      Но представим, что все методы чистые. Это значит, что их работа не зависит от состояния инстанса класса, и тогда возникает вопрос: "Зачем эти все методы содержатся в этом классе?"

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

                                  0
                                  Вместо return null лучше использовать пустой объект — Collection.empty() или null-объект — EmptyObject().

                                  Объясните, почему так? До настоящего момента приходилось встречать только вариант с null, чем он хуже?
                                    0
                                    Ну про EmptyObject неоднозначно, а вот пустая коллекция точно реже ведёт к ошибкам (притом не факт, что очевидным), чем null.
                                      +1
                                      Как по мне проще для понимания и использования. В какой то статье (или книге) приводился пример как НЕ надо возвращать значение в стиле:
                                      1) Нет друзей — возвращаем null;
                                      2) Есть один друг — возвращаем собственно объект;
                                      3) Друзей больше одного — возвращаем коллекцию объектов.
                                      Мало того что на null например можно попросту забыть проверить, или ожидать только null или коллекцию не учтя случай с одним объектом, так еще и разное поведение лепить в зависимости от типа возвращаемого значения.
                                      Тогда как при пустой коллекции или коллекции с одним элементом нам бы не пришлось в клиентском коде городить отдельную логику.
                                        +1

                                        Все так. Говоря более формальным языком, пустой список – это константа для монады "список".

                                      0
                                      По хорошему к этому манифесту книга должна прилагаться. Ибо каждый пункт имеет области применимости — тупое следование этим правилам ни к чему хорошему не приведёт…

                                      То есть каждое правило применимо, ну, скажем, в 99% случаев, но поскольку у нас тут чуть больше, чем полсотни правил, то в половине мест хотя бы одно из правил стоит нарушить…

                                      Про это недавно отдельная статья была
                                        0
                                        Я понимаю что ООП, и во всех учебниках написано, но чем автору насолили статические методы? Про состояния понятно, но с методами то в чем проблема?
                                          +1

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

                                          +3
                                          «Идеальное количество входных аргументов для функции = 0»
                                          Очень спорное утверждение.
                                            0
                                            В книге очень много спорных утверждений. На самом деле стоит просто отдавать себе отчет почему код должен работать именно таким образом каким он написан. Стоит подумать как его можно улучшить. К тому же это всего лишь рекомендации, которые не обязательно соблюдать. Это не правила, а именно рекомендации)
                                              0
                                              Идеальный код — это код который не написан, в нем нет багов и его не нужно тестировать и поддерживать.
                                              0
                                              Приблизительный максимум 20 строк и 150 символов в одной строке

                                              150 символов — это явный перебор. Большенство редакторов ставят отсечку почти на половине от этой величины. И даже это многовато.

                                              Идеальное количество входных аргументов для функции = 0

                                              Если это foo/bar/baz для hello world — да, а так нет.

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

                                              Не обязательно. Это зависит от ЯП.

                                              Не комментируй плохой код — перепиши его. Не стоит объяснять, что происходит в плохом коде, лучше сделать его явным и понятным.

                                              Это не всегда зависит от пожеланий одного разработчика. Время на рефакторинг далеко не всегда удаётся выбить.

                                              If, else, while и т.д. должны содержать вызов одной функции. Так будет читабельнее, понятнее и проще.

                                              Вообще не обязательно. Очень сомнительное правило.
                                                0
                                                Не обязательно. Это зависит от ЯП.

                                                Пример можно?
                                                Я всего на нескольких ЯП пишу. Ни в одном из них нет ограничений на имя метода.

                                                Если это foo/bar/baz для hello world — да, а так нет.

                                                • start() — идеальный метод;
                                                • start(speed) — отличный метод;
                                                • start(speed, direction, path) — похуже. Сходу и не вспомнишь, в какой последовательности параметры передавать;
                                                • start(speed, direction, path, maxBias, onError) — комментарии, думаю, излишни.
                                                  0
                                                  Пример можно?
                                                  Я всего на нескольких ЯП пишу. Ни в одном из них нет ограничений на имя метода.

                                                  Ruby. Вполне характерно писать вообще без глаголов или глагольных префиксов.
                                                  И если чистые глаголы это ещё куда не шло (#call, #perform или что-то в этом роде), то глагол + ключевое слово — это скорее code smell, чем норма.
                                                  И это не ограничение, а соглашение.

                                                  start() — идеальный метод;
                                                  start(speed) — отличный метод;
                                                  start(speed, direction, path) — похуже. Сходу и не вспомнишь, в какой последовательности параметры передавать;
                                                  start(speed, direction, path, maxBias, onError) — комментарии, думаю, излишни.

                                                  Если аргументов больше ~3 (это эмпирически) — это уже code smell.
                                                  Разумно применять keyword-аргументы, если возникает путаница.
                                                    +3
                                                    Например возьмите любую функцию из C math.h. Там нет глаголов, только существительные: sqrt, sin. log, exp, round и
                                                    Если следовать правилам чистого кода, то надо было их назвать calc_sqrt, calc_sin, find_exp и т.д. Делает ли это код чище? Ничуть.
                                                      0
                                                      Вы говорите о «общепринятых» названиях, которые
                                                      • применяются в т.ч. в математике
                                                      • приживались годами

                                                      и поэтому не вызывают дополнительных вопросов.
                                                      А вот на заре моей программистской деятельности SQR и SQRT было сложно запомнить.
                                                      Полная запись GetSqareRoot (вполне вероятно) вызывала бы меньше вопросов поскольку не является «набором несвязанных букв» (как я тогда воспринимал) а вполне осмысленным словосочетанием.
                                                        0
                                                        Да, помню свои первые попытки программировать. Особенно если учесть что английский я знал никак — почти все для меня было магическим сочетанием символов. Тогда это здорово притормозило.
                                                    0
                                                    Ruby. Вполне характерно писать вообще без глаголов или глагольных префиксов.

                                                    Я не сталкивался с Ruby.
                                                    Например, как геттеры от сеттеров отличаются?

                                                    И если чистые глаголы это ещё куда не шло (#call, #perform или что-то в этом роде), то глагол + ключевое слово — это скорее code smell, чем норма.

                                                    Из текущего:
                                                    Есть запрос (Request), который содержит список параметров (Parameter).
                                                    У Request есть метод для добавления параметра в список.
                                                    Назови я его add никто не поймет что именно добавляется.
                                                    Назови я его addParameter — даже не знакомому с архитектурой человеку будет понятно что именно добавляется в Request.

                                                    Будет ли имя addParameter «запахом»?
                                                      0

                                                      parameters.add выглядит немного лучше нежели addParameter

                                                        0
                                                        Я не сталкивался с Ruby.
                                                        Например, как геттеры от сеттеров отличаются?

                                                        Немного вклинюсь к вам просто разнообразия ради)
                                                        Objective-C
                                                        getter: `param`;
                                                        setter: `setParam:(value)` (синтаксис неточный)
                                                        Т.е. функция-геттер не имеет глагола.
                                                          0
                                                          Например, как геттеры от сеттеров отличаются?

                                                          # это геттер
                                                          def first_name
                                                            @first_name
                                                          end
                                                          
                                                          # это сеттер
                                                          def first_name=(val)
                                                            @first_name = val
                                                          end
                                                          

                                                          Вот и всё различие.
                                                          На самом деле таким макаром геттеры/сеттеры не пишут, только если надо переопределить их стандартное поведение.
                                                          Дефолтную пару можно сгенерировать с помощью одной строчки
                                                          attr_accessor :first_name
                                                          


                                                          Будет ли имя addParameter «запахом»?

                                                          Скорее да, чем нет.
                                                          Из Вашего примера, скорее всего данный функционал будет имплементирован немного по-другому.
                                                          request.params[key]=value

                                                          params — это просто словарь, к которому можно обратиться напрямую.
                                                          "[]=(key,value)" — это тоже метод.

                                                          P.S. Проверил — так примерно в рельсах и сделано. Только там params — это экземпляр класса Parameters, который в свою очередь ведёт себя как словарь.

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

                                                        Самое читаемое