Рассмотрим функцию без параметров ( edit: необязательно), которая выполняет одну строку кода и вызывается в программе только один раз (хотя не исключено, что она понадобится снова в будущем).
Он может выполнить запрос, проверить некоторые значения, сделать что-то с использованием регулярных выражений ... что-то неясное или «хакерское».
Основанием для этого было бы избежать трудно читаемых оценок:
if (getCondition()) {
// do stuff
}
где getCondition()
однострочная функция
Мой вопрос просто: это хорошая практика? Мне кажется, что все в порядке, но я не знаю о долгосрочной перспективе ...
getCondition
? Если он настолько мал и редко используется, как вы говорите, то присвоение ему имени ничего не значит.Ответы:
Зависит от этой одной строки. Если строка читаема и кратка сама по себе, функция может не понадобиться. Упрощенный пример:
OTOH, если функция дает хорошее имя для строки кода, содержащей, например, сложное, трудно читаемое выражение, это совершенно оправдано (для меня). Придуманный пример (разбит на несколько строк для удобства чтения):
источник
taxPayer
является глобальным в этом сценарии. Возможно, этот класс естьTaxReturn
иtaxPayer
является атрибутом.Да, это может быть использовано для удовлетворения передового опыта. Например, лучше иметь функцию с четким именем, выполняющую некоторую работу, даже если длина ее составляет всего одну строку, чем иметь эту строку кода в более крупной функции и требовать однострочный комментарий, объясняющий, что она делает. Кроме того, соседние строки кода должны выполнять задачи на одном уровне абстракции. Контрпример был бы что-то вроде
В этом случае определенно лучше переместить среднюю строку в функцию с разумным именем.
источник
petrolFlag |= 0x006A;
без какого-либо принятия решения, было бы лучше просто сказатьpetrolFlag |= A_B_C;
без дополнительной функции. Предположительно, егоengageChoke()
следует вызывать только в том случае, если онpetrolFlag
соответствует определенным критериям, и в нем должно быть четко сказано: «Мне нужна функция здесь». Просто небольшая гнида, этот ответ, в основном, точный, в противном случае :)mixLeadedGasoline()
, вам бы не пришлось!Я думаю, что во многих случаях такая функция является хорошим стилем, но вы можете рассматривать локальную логическую переменную как альтернативу в тех случаях, когда вам не нужно использовать это условие где-то в других местах, например:
Это даст подсказку читателю кода и избавит от введения новой функции.
источник
IsEngineReadyUnlessItIsOffOrBusyOrOutOfService
).В дополнение к ответу Питера , если это условие, возможно, потребуется обновить в какой-то момент в будущем, инкапсулируя его так, как вы предлагаете, у вас будет только одна точка редактирования.
Следуя примеру Петра, если это
становится этим
Вы делаете одно редактирование, и оно обновляется повсеместно. Ремонтопригодность мудрая, это плюс.
С точки зрения производительности, большинство оптимизирующих компиляторов в любом случае удалит вызов функции и вставит небольшой блок кода. Оптимизация чего-то подобного может на самом деле уменьшить размер блока (удаляя инструкции, необходимые для вызова функции, возврата и т. Д.), Поэтому обычно это безопасно делать даже в условиях, которые в противном случае могли бы предотвратить встраивание.
источник
seemsGreen
это будет ненадежно с легкими объектами, не будет иметь значения, если код никогда не заботится о том, зеленые ли легкие объекты. Однако, если определение «облегченного» изменяется так, что некоторые не зеленые объекты, для которых возвращается значение trueseemsGreen
, не отображаются как «облегченные», то такое изменение в определении «облегченного» может нарушить код, который проверяет объекты быть "зеленым". В некоторых случаях совместное тестирование зеленого цвета и веса в коде может сделать отношения между тестами более ясными, чем если бы они были отдельными методами.В дополнение к удобочитаемости (или в дополнение к ней) это позволяет писать функции на должном уровне абстракции.
источник
По-разному. Иногда лучше инкапсулировать выражение в функцию / метод, даже если это всего одна строка. Если читать сложно или вам это нужно в нескольких местах, тогда я считаю это хорошей практикой. В долгосрочной перспективе его легче поддерживать, поскольку вы ввели единую точку изменений и улучшенную читаемость .
Однако иногда это просто то, что вам не нужно. Если выражение легко читается и / или просто появляется в одном месте, не оборачивайте его.
источник
Я думаю, что если у вас их всего несколько, то это нормально, но проблема возникает, когда их много в вашем коде. И когда запускается компилятор или интерпретатор (в зависимости от языка, который вы используете), он отправляется к этой функции в памяти. Допустим, у вас есть 3 из них, я не думаю, что компьютер заметит, но если вы начнете иметь сотни из этих мелких вещей, то система должна зарегистрировать функции в памяти, которые вызываются только один раз, а затем не уничтожаются.
источник
Я сделал это точно недавно в приложении, которое я рефакторинг, чтобы сделать явный смысл кода без комментариев:
источник
if
короткую позицию? Этот локальный (лямбда) подход делаетPaymentButton_Click
функцию (в целом) труднее для чтения.lblCreditCardError
В вашем примере , как представляется, является членом, так иHaveError
есть (частный) предикат , который действителен для объекта. Я бы склонялся к тому, чтобы понизить это, но я не программист на C #, поэтому я сопротивляюсь.CheckInputs()
???Перемещение этой строки в метод с именем с именем облегчает чтение вашего кода. Многие другие уже упоминали это («самодокументируемый код»). Другое преимущество переноса его в метод состоит в том, что он облегчает юнит-тестирование. Когда он изолирован в своем собственном методе и проверен модулем, вы можете быть уверены, что если / когда будет обнаружена ошибка, его не будет в этом методе.
источник
Хороших ответов уже много, но стоит упомянуть особый случай .
Если ваш однострочный оператор нуждается в комментарии , и вы можете четко определить (что означает: имя) его назначение, рассмотрите возможность извлечения функции при расширении комментария в документ API. Таким образом, вы сделаете вызов функции быстрее и понятнее.
Интересно, что то же самое можно сделать, если в настоящее время делать нечего, кроме комментария, напоминающего о необходимых расширениях (в ближайшем будущем 1) ), так что это,
может также измениться в этом
1) вы должны быть действительно уверены в этом (см. Принцип ЯГНИ )
источник
Если язык поддерживает это, я обычно использую помеченные анонимные функции для достижения этой цели.
ИМХО, это хороший компромисс, потому что он дает вам удобство чтения, так как сложное выражение не загромождает
if
условие, избегая загромождения пространства имен global / package с маленькими одноразовыми метками. Дополнительным преимуществом является то, что функция «определение» находится там, где она используется, что упрощает изменение и чтение определения.Это не только предикатные функции. Мне также нравится заключать повторяющиеся шаблоны в небольшие функции, подобные этой (это особенно хорошо работает для генерации списка pythonic без загромождения синтаксиса скобок). Например, следующий упрощенный пример при работе с PIL в python
источник
[] == False
ни какого-либо другого похожая питоническая эквивалентность, которая не всегда интуитивна. Это в основном способ пометить, что someCondition на самом деле является предикатом.[] != False
но[]
является ложным, когда приведен кlen([complicated expression producing a list]) == 0
, а не использовать,True if [blah] else False
что все еще требует, чтобы читатель знал, что [] оценивает как False.