Предположим, у меня есть длинный метод, подобный этому:
public void SomeLongMethod()
{
// Some task #1
...
// Some task #2
...
}
Этот метод не имеет повторяющихся частей, которые должны быть перемещены в отдельный метод или локальную функцию.
Есть много людей (включая меня), которые думают, что длинные методы - это запах кода. Также мне не нравится идея использования #region
здесь, и есть очень популярный ответ, объясняющий, почему это плохо .
Но если я разделю этот код на методы
public void SomeLongMethod()
{
Task1();
Task2();
}
private void Task1()
{
// Some task #1
...
}
private void Task2()
{
// Some task #1
...
}
Я вижу следующие проблемы:
Загрязнение области определения класса определениями, которые используются внутри одного метода и которые означают, что я должен где-то документировать это
Task1
иTask2
предназначены только для внутренних целейSomeLongMethod
(или каждый, кто читает мой код, должен будет прийти к выводу об этой идее).Загрязнение автозаполнения IDE (например, Intellisense) методов, которые будут использоваться только один раз внутри одного
SomeLongMethod
метода.
Так что, если я разделю этот код метода на локальные функции
public void SomeLongMethod()
{
Task1();
Task2();
void Task1()
{
// Some task #1
...
}
void Task2()
{
// Some task #1
...
}
}
тогда у этого нет недостатков отдельных методов, но это не выглядит лучше (по крайней мере для меня), чем оригинальный метод.
Какая версия SomeLongMethod
более удобна для чтения и почему?
источник
Ответы:
Автономные задачи должны быть перемещены в автономные методы. Недостатка достаточно много, чтобы преодолеть эту цель.
Вы говорите, что они загрязняют пространство имен класса, но это не тот компромисс, на который вы должны обращать внимание при анализе кода. Будущий читатель класса (например, вы) с гораздо большей вероятностью спросит: «Что делает этот конкретный метод и как я должен изменить его, чтобы он делал то, что говорят измененные требования?» чем «Какова цель и смысл существования всех методов в классе? » Следовательно, облегчить понимание каждого из методов (сделав так, чтобы в нем было меньше элементов), гораздо важнее, чем облегчить понимание всего класса. (сделав так, чтобы у него было меньше методов).
Конечно, если задачи не являются действительно автономными, но требуют перемещения некоторых переменных состояния, тогда вместо этого может быть правильным выбор объекта метода, вспомогательного объекта или аналогичной конструкции. И если задачи полностью автономны и вообще не связаны с областью приложения (например, просто форматирование строк, то, возможно, они должны перейти в совершенно другой (служебный) класс. Но это не меняет того факта, что " подавление методов на класс "в лучшем случае является очень вспомогательной целью.
источник
Мне не нравится ни один подход. Вы не предоставили более широкий контекст, но в большинстве случаев это выглядит так:
У вас есть класс, который выполняет некоторую работу, объединяя возможности нескольких служб в один результат.
Каждый из ваших сервисов реализует только часть логики. Что-то особенное, что может сделать только этот сервис. Если у него есть другие частные методы, кроме тех, которые поддерживают основной API, вы можете легко их отсортировать, и их не должно быть слишком много.
Суть в следующем: если вы начнете создавать области в своем коде для группировки методов, самое время подумать об инкапсуляции их логики с новым сервисом.
источник
Проблема с созданием функций в методе заключается в том, что он не уменьшает длину метода.
Если вам нужен дополнительный уровень защиты «private to method», вы можете создать новый класс
Но классы на уроках очень страшные: /
источник
Хорошей практикой является минимизация объема языковых конструкций, таких как переменные и методы. Например, избегайте глобальных переменных. Это облегчает понимание кода и помогает избежать неправильного использования, потому что конструкция может быть доступна в меньшем количестве мест.
Это говорит в пользу использования локальных функций.
источник
Я бы согласился, что длинные методы часто являются запахом кода, но я не думаю, что это целая картина, скорее, именно поэтому длинный метод указывает на проблему. Мое общее правило: если код выполняет несколько разных задач, то каждая из этих задач должна иметь свой собственный метод. Для меня имеет значение, являются ли эти разделы кода повторяющимися или нет; если вы действительно не абсолютно уверены, что никто не захочет по отдельности вызывать их по отдельности в будущем (а это очень сложно!), используйте их в другом методе (и сделайте его закрытым), что должно быть очень сильным показателем Вы не ожидаете, что это будет использоваться за пределами класса).
Я должен признаться, что я еще не использовал локальные функции, поэтому мое понимание здесь далеко не полное, но ссылка, которую вы предоставили, предполагает, что они часто будут использоваться аналогично лямбда-выражению (хотя здесь есть несколько вариантов использования где они могут быть более подходящими, чем лямбда, или где вы не можете использовать лямбду, см. Локальные функции по сравнению с лямбда-выражениями для уточнения). Вот тогда, я думаю, это может быть связано с гранулярностью «других» задач; если они довольно тривиальны, то, возможно, локальная функция будет в порядке? С другой стороны, я видел примеры гигантских лямбда-выражений (вероятно, когда разработчик недавно обнаружил LINQ), которые сделали код гораздо менее понятным и понятным, чем если бы его просто вызывали из другого метода.
На странице « Местные функции» говорится, что:
Я не уверен, что я действительно с MS на этом в качестве причины для использования. Объем вашего метода (вместе с его именем и комментариями) должен прояснить, каково было ваше намерение в то время . С локальной функцией я мог видеть, что другие разработчики могут видеть ее более священной, но потенциально до такой степени, что, если в будущем произойдут изменения, требующие повторного использования этой функции, они напишут свою собственную процедуру и оставят локальную функцию на месте. ; тем самым создавая проблему дублирования кода. Последнее предложение из приведенной выше цитаты может быть уместным, если вы не доверяете членам команды понять частный метод перед его вызовом, и поэтому называете его ненадлежащим образом (поэтому это может повлиять на ваше решение, хотя в данном случае образование будет лучшим вариантом) ,
Таким образом, в целом, я бы предпочел разделить на методы, но MS по какой-то причине написала Local Functions, так что я бы точно не сказал, что не используйте их,
источник