Всякий раз, когда я обнаруживаю, что пишу одну и ту же логику более одного раза, я обычно встраиваю ее в функцию, поэтому в моем приложении есть только одно место, где я должен поддерживать эту логику. Побочным эффектом является то, что я иногда получаю одну или две строчные функции, такие как:
function conditionMet(){
return x == condition;
}
ИЛИ ЖЕ
function runCallback(callback){
if($.isFunction(callback))
callback();
}
Это ленивый или плохая практика? Я только спрашиваю, потому что это приводит к большему количеству вызовов функций для очень маленьких кусочков логики.
programming-practices
coding-standards
Марк Браун
источник
источник
Assert.AreEqual<int>(expected, actual, message, arg1, arg2, arg3, ...);
. Второй хорошо как есть. Я бы потенциально включил необязательный флаг bool, который будет указывать, следует ли генерировать исключение / etc. в случае, если обратный вызов не является функцией.def yes(): return 'yes'
Ответы:
Хе-хе, о мистер Браун, если бы я только мог убедить всех разработчиков, с которыми я встречался, держать их функции такими маленькими, поверьте мне, мир программного обеспечения был бы лучше!
1) Читаемость вашего кода увеличивается в десять раз.
2) Так легко понять процесс вашего кода из-за читабельности.
3) СУХОЙ - Не повторяйся - Ты очень хорошо согласуешься с этим!
4) Тестируемый. Крошечные функции в миллион раз легче тестировать, чем те 200-строчные методы, которые мы видим слишком часто.
Да, и не беспокойтесь о «переключении функций» с точки зрения производительности. «Выпуск» сборок и оптимизация компилятора очень хорошо позаботились об этом для нас, а производительность составляет 99% времени где-то еще в проектировании систем.
Это ленивый? - Совсем наоборот!
Это плохая практика? - Точно нет. Лучше использовать этот способ создания методов, чем смоляные шарики или «Объекты Бога», которые слишком распространены.
Продолжайте в том же духе, мой товарищ по ремеслу;)
источник
Я бы сказал, что рефакторированный метод слишком короткий, если либо:
Пример:
или же...
Пример:
Это может быть допустимым шаблоном, но я бы просто включил метод configureDialog () в этом примере, если только я не намеревался переопределить его или повторно использовать этот код в другом месте.
источник
Может ли функция быть слишком короткой? В общем нет.
На самом деле единственный способ обеспечить, чтобы:
Это сохранить ваши функции как можно меньше. Или, другими словами, извлекайте функции из ваших функций, пока вы не сможете больше их извлекать. Я называю это «Извлекай, пока не упадешь».
Чтобы объяснить это: функция - это область с функциональными частями, которые взаимодействуют через переменные. Класс также является областью с функциональными частями, которые взаимодействуют через переменные. Таким образом, длинная функция всегда может быть заменена одним или несколькими классами с небольшим методом.
Кроме того , функция , которая является достаточно большим , чтобы позволить вам извлечь еще одну функцию из нее, делает больше , чем одну вещь по определению . Поэтому, если вы можете извлечь функцию из другой, вы должны извлечь эту функцию.
Некоторые люди беспокоятся, что это приведет к расширению функций. Они правы. Будет. Это на самом деле хорошая вещь. Это хорошо, потому что у функций есть имена. Если вы тщательно выбираете добрые имена, то эти функции действуют как подписывающие сообщения, которые направляют других людей через ваш код. Действительно, хорошо именованные функции внутри хорошо именованных классов внутри хорошо именованных пространств имен являются одним из лучших способов убедиться, что ваши читатели НЕ теряются.
В Эпизоде III «Чистого кода» об этом есть еще много всего на cleancoders.com
источник
Вау, большинство из этих ответов не очень полезны.
Не должно быть написано ни одной функции, чья идентичность является ее определением . То есть, если имя функции - это просто блок кода функции, написанный на английском языке, то не пишите его как функцию.
Рассмотрим вашу функцию
conditionMet
и эту другую функциюaddOne
(простите за мой ржавый JavaScript):conditionMet
правильное концептуальное определение;addOne
это тавтология .conditionMet
это хорошо, потому что вы не знаете, чтоconditionMet
влечет за собой просто говоря «условие выполнено», но вы можете понять, почемуaddOne
это глупо, если вы прочитаете это на английском:Ради любви ко всему, что еще может быть святым, пожалуйста, не пишите тавтологических функций!
(И по той же причине не пишите комментарии для каждой строки кода !)
источник
function nametoolong() { return name.size > 15; }
илиfunction successorIndex(x) { return x + 1; }
Так что проблема с вашими функциями на самом деле просто в том, что их имя неверно.Я бы сказал, что если вы думаете, что намерение какого-то кода можно улучшить, добавив комментарий, то вместо добавления этого комментария извлеките код в свой собственный метод. Неважно, насколько маленьким был код.
Так, например, если ваш код будет выглядеть так:
вместо этого сделайте так:
с участием
Или, другими словами, речь идет не о длине метода, а о самодокументированном коде.
источник
if x == PIXEL_ON
. Использование константы может быть таким же описательным, как использование метода, и немного короче.Я думаю, что это именно то, что вы хотите сделать. Сейчас эта функция может состоять только из одной или двух строк, но со временем она может расти. Также наличие большего количества вызовов функций позволяет читать вызовы функций и понимать, что происходит внутри них. Это делает ваш код очень СУХИМ (не повторяется), что намного удобнее в обслуживании.
источник
conditionMet
является слишком общим именем и не принимает аргументов, поэтому он проверяет некоторое состояние? (x == xCondition) в большинстве языков и ситуаций столь же выразителен, как и «xConditition».Я согласен со всеми другими постами, которые я видел. Это хороший стиль.
Издержки такого маленького метода могут быть равны нулю, так как оптимизатор может оптимизировать вызов и встроить код. Простой код, подобный этому, позволяет оптимизатору выполнять свою работу наилучшим образом.
Код должен быть написан для ясности и простоты. Я пытаюсь ограничить метод одной из двух ролей: принятие решений; или выполнение работы. Это может генерировать однострочные методы. Чем лучше я это делаю, тем лучше я нахожу свой код.
Подобный код имеет тенденцию иметь высокую когезию и низкую связь, что является хорошей практикой кодирования.
РЕДАКТИРОВАТЬ: примечание о названиях методов. Используйте имя метода, которое указывает, что метод делает не так, как он это делает. Я считаю, что verb_noun (_modifier) - это хорошая схема именования. Это дает имена вроде Find_Customer_ByName, а не Select_Customer_Using_NameIdx. Второй случай может стать неправильным при изменении метода. В первом случае вы можете заменить всю реализацию базы данных клиентов.
источник
Рефакторинг одной строки кода в функцию кажется чрезмерным. Могут быть исключительные случаи, такие как строки veroooooong / comples или выражения, но я бы не стал этого делать, если бы не знал, что функция будет расти в будущем.
и ваш первый пример намекает на использование глобальных переменных (которые могут или не могут говорить о других проблемах в коде), я бы еще больше изменил его рефакторинг и сделал бы эти две переменные параметрами:
conditionMet
Пример может быть полезным , если условие было долгим и повторяющимся , такие как:источник
conditionMet
функция просто многословный==
оператор. Это вероятно не полезно.conditionMet (x, relation condition) {
здесь, где вы передаете х, '==' и отношение. Тогда вам не нужно повторять код для «<», «>», «<=», «! =» И так далее. С другой стороны - в большинстве языков эти конструкции встроены, поскольку операторы (условие x ==) делают именно это. Функции для атомарных операторов - еще один шаг.Учти это:
Простая функция обнаружения столкновений:
Если вы все время пишете этот «простой» один элемент в вашем коде, вы можете в конечном итоге ошибиться. Плюс, было бы очень мучительно писать это снова и снова.
источник
#define
;)Нет, и это редко проблема. Теперь, если кто-то считает, что ни одна функция не должна быть длиннее одной строки кода (если бы это могло быть так просто), это было бы проблемой и в некотором смысле ленивым, потому что он не думал о том, что уместно.
источник
function isAdult () = { age >= 18; }
но не обязательноisAtLeast18
.Я бы сказал, что они слишком короткие, но это мое субъективное мнение.
Потому что:
Длинные функции - это плохо, но функции, которые короче 3-х строк и выполняют только одну вещь, одинаково плохи ИМХО.
Так что я бы сказал, написать только небольшую функцию, если это:
Бьюсь об заклад, у следующего разработчика (старшего) будут дела поважнее, чем помнить все ваши функции SetXToOne. Так что в любом случае они скоро превратятся в мертвый вес.
источник
Мне не нравится пример нет. 1, потому что это общее имя.
conditionMet
не кажется общим, так что означает конкретное условие? подобноЭто было бы хорошо. Это семантическая разница, в то время как
не будет хорошо для меня.
Может быть, он часто используется и может быть предметом последующих изменений:
тоже хорошо. Используя его несколько раз, вам просто нужно поменять одно место, если вам нужно - возможно, взбитые сливки станут возможными завтра.
не атомарный, и должен дать вам хорошую возможность для тестирования.
Если вам нужно передать функцию, конечно, передайте все, что вам нравится, и напишите глупо выглядящие функции.
Но в целом я вижу гораздо больше функций, которые слишком длинные, чем функции, которые слишком короткие.
Последнее слово: некоторые функции выглядят только уместно, потому что они написаны слишком многословно:
Если вы видите, что это так же, как
у вас не будет проблем с
вместо
источник
Там нет кода, как нет кода!
Сохраняйте это простым и не усложняйте вещи.
Это не лень, это делает вашу работу!
источник
Да, нормально иметь функцию короткого кода. Как упоминалось в предыдущих ответах, очень часто встречаются такие методы, как «геттеры», «сеттеры», «аксессоры».
Иногда эти короткие функции доступа являются виртуальными, потому что при переопределении в подклассах функции будут иметь больше кода.
Если вы хотите, чтобы ваша функция была не такой короткой, ну, во многих функциях, будь то глобальные или методы, я обычно использую переменную «result» (стиль Паскаля) вместо прямого возврата, что очень полезно при использовании отладчика.
источник
Слишком короткий, никогда не является проблемой. Некоторые причины для коротких функций:
Повторное использование
Например, если у вас есть функция, например, метод set, вы можете утверждать, что параметры верны. Эта проверка должна выполняться везде, где установлена переменная.
Ремонтопригодность
Вы можете использовать какое-то утверждение, которое, по вашему мнению, в будущем может измениться. Например, теперь вы показываете символ в столбце, но позже он может измениться на что-то другое (или даже звуковой сигнал).
единообразие
Вы используете, например, шаблон фасада, и единственное, что делает функция, это точно передает функцию другой, не меняя аргументы.
источник
Когда вы даете разделу кода имя, оно, по сути, дает ему имя . Это может быть по любой из нескольких причин, но критический момент заключается в том, можете ли вы дать ему осмысленное имя, которое добавляет вашу программу. Такие имена, как «addOneToCounter», ничего бы не добавили, но
conditionMet()
сделали бы.Если вам нужно правило для определения, является ли фрагмент слишком коротким или слишком длинным, подумайте, сколько времени вам понадобится, чтобы найти значимое имя для фрагмента. Если вы не можете в течение разумного промежутка времени, фрагмент не подходит.
источник
Нет, но это может быть слишком кратко.
Помните: код пишется один раз, но читается много раз.
Не пишите код для компилятора. Напишите это для будущих разработчиков, которым придется поддерживать ваш код.
источник
Да, дорогая, функция может быть все меньше и меньше, и будет она хорошей или плохой, это зависит от используемого вами языка / платформы.
По моему мнению, я в основном работаю над интерфейсными технологиями, малые функции в основном используются в качестве вспомогательных функций, которые вы будете обязаны использовать их как много, работая с небольшими фильтрами и используя ту же логику в вашем приложении. Если ваше приложение имеет слишком много общей логики, тогда будет множество мелких функций.
Но в приложении, где у вас нет общей логики, вы не будете обязаны делать маленькие функции, но вы можете разбить свой код на сегменты, где вам будет легко управлять и понимать.
В общем, разбить ваш огромный код на маленькие функции - очень хороший подход. В современных рамках и языках вы будете обязаны делать это, например,
является анонимной функцией в JavaScript и Typescript ES 2017
В приведенном выше коде вы можете увидеть 3 объявления функций и 2 вызова функций. Это простой вызов службы в Angular 4 с Typescript. Вы можете думать об этом как о своих требованиях
Выше приведены 3 анонимные функции на языке Clojure
Вышеуказанное является функциональным объявлением в ближайшем будущем.
Так что да, функции могут быть как меньше, но хорошо это или плохо, если у вас есть такие функции, как:
Что ж, это не очень хорошая практика, но что, если вы используете эту функцию в теге HTML, как мы это делаем в Angular Framework, если не было поддержки увеличения или уменьшения в шаблонах Angular HTML, тогда это было бы решением для меня.
Давайте возьмем другой пример
Приведенный выше пример является обязательным при воспроизведении массивов внутри Angular HTML Templates. Так что иногда вам придется создавать небольшие функции
источник
Я не согласен с почти ответом, данным в это время.
Недавно я нашел коллегу, который пишет всем ученикам, например, следующее:
Это может быть хорошим кодом в спорадических случаях, но, конечно, нет, если вы определяете много классов, имеющих много и много свойств. При этом я не хочу сказать, что методы, подобные приведенным выше, не должны быть написаны. Но если вы заканчиваете тем, что пишете большую часть кода как «обертку» реальной логики, что-то не так.
Вероятно, программист упускает общую логику, опасается будущих изменений и рефакторинга кода.
Определение интерфейса - потому что реальная потребность; действительно, если вам нужно установить и получить простое свойство (без особой логики, которое делает член короче), это будет возможно. Но если реальная потребность может быть проанализирована по-другому, почему бы не определить более интуитивный интерфейс?
Чтобы действительно ответить на вопрос, конечно, нет, и причина очень очевидна: метод / свойство / whatelse должен быть определен для того, что ему нужно. Даже пустая виртуальная функция имеет причину существования.
источник