Подтвердить что ты не робот

Лучшие практики: многие мелкие функции/методы или более крупные функции с встроенными логическими компонентами процесса?

Лучше ли написать много маленьких методов (или функций) или просто написать логику/код этих небольших процессов прямо в то место, где вы бы назвали небольшой метод? Как насчет того, чтобы разбить код на небольшую функцию, даже если пока он только вызывается из одного места?

Если один выбор зависит от некоторых критериев, каковы они; как программист должен сделать правильный выбор?

Я надеюсь, что ответ может быть применен, как правило, на многих языках, но при необходимости ответы могут быть конкретными для языка или языков. В частности, я думаю о SQL (функции, правила и хранимые процедуры), Perl, PHP, Javascript и Ruby.

4b9b3361

Ответ 1

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

Fowler Рефакторинг - это все об этой теме, и я настоятельно рекомендую его.

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

Ответ 2

Размер метода напрямую связан с его циклической сложностью.

Основные преимущества сохранения размера метода (что означает разделение большого метода на несколько небольших методов):

  • лучшее тестирование модулей (из-за низкой циклической сложности)
  • лучшая отладка из-за более явной трассировки стека (вместо одной ошибки в одном гигантском методе)

Ответ 3

Как всегда, вы можете сказать: это зависит. Это скорее вопрос именования и определения задачи метода. Каждый метод должен выполнять одну (не более) четко определенную задачу и должен делать это полностью. Имя метода должно указывать на задачу. Если ваш метод называется DoAandB(), лучше иметь отдельные методы DoA() и DoB(). Если вам нужны такие методы, как setupTask, executeTask, FinishTask, может быть полезно объединить их.

Некоторые точки, указывающие, что может быть полезно объединение разных методов:

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

Некоторые точки, указывающие, что разделение метода может быть полезным:

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

В качестве объяснения аргумента unit-test: я написал метод, который сделал некоторые вещи, включая IO. IO-часть была очень трудной для тестирования, поэтому я подумал об этом. Я пришел к выводу, что мой метод сделал 5 логических и независимых шагов, и только один из них задействовал IO. Поэтому я разделил свой метод на 5 меньших, четыре из них были легко протестированы.

Ответ 4

Маленькие методы каждый раз.

Они самодокументируются (er, если хорошо названы)

Они разбивают проблему на управляемые части - вы являетесь KeepingItSimple.

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

Они проверяются на единицу. Это убийца, вы просто не можете использовать unit test какой-нибудь огромный метод, выполняющий нагрузку задач

Ответ 5

Что-то, что я узнал из книги "Кодекс":

  • Напишите методы/функции, чтобы они реализовать один кусок (или блок или задачу) логики. Если это требует разбивки в подзадачи, затем напишите отдельный метод/функция для них и назовите их.
  • Если я нахожу, что метод/функция имя становится длинным, тогда я пытаюсь рассмотрите метод, чтобы увидеть, как он может разбить на два метода.

Надеюсь, что это поможет

Ответ 6

Некоторые эмпирические правила:

  • Функции не должны быть длиннее, чем можно отображать на экране
  • Разбить функции на более мелкие, если сделать код более читаемым.

Ответ 7

Чем больше метод, тем сложнее проверить и поддерживать. Мне гораздо легче понять, как работает большой процесс, когда он разбивается на атомарные этапы. Кроме того, это отличный первый шаг, чтобы сделать ваши классы расширяемыми. Вы можете отметить эти отдельные шаги как виртуальные (для наследования) или переместить их в другие объекты (состав), что упростит настройку вашего приложения.

Ответ 8

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

Ответ 9

Я считаю, что наличие множества небольших методов упрощает чтение, поддержку и отладку кода.

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

Это похоже на работу, но в конечном итоге экономит время.

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

Ответ 10

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

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

Ответ 11

Лично я склоняюсь в сторону, предпочитая более мелкие методы, но не до религиозного стремления к максимальному количеству строк. Мой основной критерий или цель - сохранить мой код DRY. В тот момент, когда у меня есть кодовый блок, который дублируется (будь то по духу или фактически по тексту), даже если он может быть длиной 2 или 4 строки, я DRY создаю этот код в отдельный метод. Иногда я буду делать это заранее, если я думаю, что есть хорошие шансы, что он будет использован снова в будущем.

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

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

Ответ 12

Это немного зависит от мышления. Тем не менее, это не упрямый вопрос.

Ответ скорее зависит от контекста языка.

В мире Java/С#/C++, где люди следуют школе "чистого кода", как проповедовал Роберт Мартин, тогда: многие малые методы - это путь.

Метод имеет четкое имя и делает одно. Один уровень гнездования, что он. Это ограничивает его длину до 3, 5, максимум 10 строк.

И честно: я считаю, что этот способ кодирования абсолютно превосходит любой другой "стиль".

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

Итак, единственная "законная" причина использовать "все, что входит в один метод/функцию", - это когда вся ваша команда работает так и предпочитает этот стиль. Или, когда вы не можете использовать приличную инструментальную оснастку (но тогда переходить к этой большой уродливой функции тоже не удастся).