C # позволяет использовать ключевые слова #region
/, #endregion
чтобы сделать области кода разборными в редакторе. Всякий раз, когда я делаю это, я делаю это, чтобы скрыть большие куски кода, которые, вероятно, могут быть преобразованы в другие классы или методы. Например, я видел методы, которые содержат 500 строк кода с 3 или 4 областями, просто чтобы сделать его управляемым.
Таким образом, разумное использование регионов является признаком проблемы? Мне кажется, так оно и есть.
c#
code-smell
Крейг
источник
источник
Ответы:
Запах кода - это признак, который указывает на наличие проблемы в проекте, которая потенциально может увеличить количество ошибок: это не относится к регионам, но регионы могут способствовать созданию запахов кода, таких как длинные методы.
Поскольку:
регионы - это анти-паттерны. Они требуют больше работы, которая не повышает качество или удобочитаемость кода, не уменьшает количество ошибок и может только усложнить код для рефакторинга.
Не используйте регионы внутри методов; вместо этого рефакторинг
Методы должны быть короткими . Если в методе всего десять строк, вы, вероятно, не использовали бы регионы, чтобы скрыть пять из них при работе с другими пятью.
Кроме того, каждый метод должен выполнять одну-единственную вещь . Регионы, с другой стороны, предназначены для разделения разных вещей . Если ваш метод выполняет A, то B, логично создать две области, но это неправильный подход; вместо этого вы должны изменить метод на два отдельных метода.
Использование регионов в этом случае также может усложнить рефакторинг. Представь, что у тебя есть:
Свернуть первую область, чтобы сконцентрироваться на второй, не только рискованно: мы можем легко забыть об исключении, останавливающем поток (
return
вместо него может быть предложено защитное предложение , которое еще труднее обнаружить), но также возникнет проблема если код должен быть реорганизован таким образом:Теперь регионы не имеют смысла, и вы не можете прочитать и понять код во второй области, не глядя на код в первой.
Другой случай, который я иногда вижу, это:
Соблазнительно использовать регионы, когда проверка аргументов начинает охватывать десятки LOC, но есть лучший способ решить эту проблему: тот, который используется исходным кодом .NET Framework:
Не используйте регионы вне методов для группировки
Некоторые люди используют их для группировки полей, свойств и т. Д. Этот подход неправильный: если ваш код совместим с StyleCop, тогда поля, свойства, частные методы, конструкторы и т. Д. Уже сгруппированы и их легко найти. Если это не так, то пришло время задуматься о применении правил, обеспечивающих единообразие в вашей кодовой базе.
Другие люди используют регионы, чтобы скрыть множество похожих объектов . Например, если у вас есть класс с сотнями полей (который составляет не менее 500 строк кода, если вы подсчитываете комментарии и пробелы), у вас может возникнуть желание поместить эти поля в область, свернуть ее и забыть о них. Опять же, вы делаете это неправильно: с таким количеством полей в классе вам следует лучше подумать об использовании наследования или разбить объект на несколько объектов.
Наконец, некоторые люди испытывают желание использовать регионы для группировки связанных вещей : событие с его делегатом или метод, связанный с IO, с другими методами, связанными с IO, и т. Д. В первом случае это становится беспорядком, который трудно поддерживать читать и понимать Во втором случае лучшим дизайном, вероятно, будет создание нескольких классов.
Есть ли хорошее применение для регионов?
Нет . Было наследство использование: сгенерированный код. Тем не менее, инструменты генерации кода просто должны использовать частичные классы. Если в C # есть поддержка регионов, то это в основном потому, что это устаревшее использование, и теперь, когда слишком много людей использовали регионы в своем коде, было бы невозможно удалить их, не нарушая существующие кодовые базы.
Думайте об этом как о
goto
. Тот факт, что язык или IDE поддерживает функцию, не означает, что она должна использоваться ежедневно. Правило StyleCop SA1124 ясно: вы не должны использовать регионы. Никогда.Примеры
В настоящее время я делаю обзор кода моего коллега кода. Кодовая база содержит много областей, и на самом деле является прекрасным примером того, как не использовать области и почему области приводят к плохому коду. Вот некоторые примеры:
4 000 LOC монстр:
Недавно я где-то читал на сайте Programmers.SE, что, когда файл содержит слишком много
using
s (после выполнения команды «Удалить неиспользуемые использования»), это хороший признак того, что класс внутри этого файла делает слишком много. То же самое относится и к размеру самого файла.Просматривая код, я наткнулся на 4 000 LOC-файлов. Оказалось, что автор этого кода просто копировал один и тот же 15-строчный метод сотни раз, слегка изменяя имена переменных и вызываемый метод. Простое регулярное выражение позволило обрезать файл с 4 000 LOC до 500 LOC, просто добавив несколько обобщений; Я почти уверен, что при более умном рефакторинге этот класс может быть сокращен до нескольких десятков строк.
Используя регионы, автор поощряет себя игнорировать тот факт, что код невозможно поддерживать и плохо написан, и сильно дублировать код вместо его рефакторинга.
Регион «До А», Регион «До Б»:
Другим отличным примером был метод инициализации монстра, который просто выполнял задачу 1, затем задачу 2, затем задачу 3 и т. Д. Было пять или шесть задач, которые были полностью независимыми, каждая из которых инициализировала что-то в классе контейнера. Все эти задачи были сгруппированы в один метод и сгруппированы по регионам.
Это имело одно преимущество:
Проблемы, с другой стороны, были множественными:
Не было очевидно, были ли зависимости между регионами. Надеемся, что не было повторного использования переменных; в противном случае, обслуживание может стать еще большим кошмаром.
Метод было практически невозможно проверить. Как бы вы легко узнали, что метод, который делает двадцать вещей одновременно, делает их правильно?
Область полей, область свойств, область конструктора:
Рассмотренный код также содержал множество областей, объединяющих все поля вместе, все свойства вместе и т. Д. Это имело очевидную проблему: рост исходного кода.
Когда вы открываете файл и видите огромный список полей, вы более склонны сначала выполнить рефакторинг класса, а затем работать с кодом. С регионами вы берете привычку рушиться и забывать об этом.
Другая проблема заключается в том, что если вы будете делать это повсеместно, вы обнаружите, что создаете области из одного блока, что не имеет никакого смысла. Это было на самом деле в коде, который я рассмотрел, где было много
#region Constructor
содержащих один конструктор.Наконец, поля, свойства, конструкторы и т. Д. Уже должны быть в порядке . Если они совпадают и соответствуют соглашениям (константы, начинающиеся с заглавной буквы и т. Д.), То уже ясно, где останавливается тип элементов и начинается другой, поэтому вам не нужно явно создавать для этого регионы.
источник
Для меня невероятно, сколько людей так страстно ненавидят регионы!
Я полностью согласен со многими из их возражений: засунуть код,
#region
чтобы скрыть его от глаз, - это плохо. Разделение класса на то,#regions
когда он должен быть подвергнут рефакторингу на отдельные классы, является очевидной ошибкой. Использование#region
встраивания избыточной семантической информации, ну, в общем, избыточно.Но ни одна из этих вещей не означает , что есть что - нибудь по существу неправильно с использованием областей в коде! Я могу только предположить, что большинство людей возражают против того, что они работали в командах, где другие склонны неправильно использовать такие возможности IDE, как эта. Я могу позволить себе роскошь работать в начальной школе, и я ценю то, как регионы помогли организовать мой рабочий процесс. Может быть, это мое навязчивое компульсивное расстройство, но мне не нравится видеть на экране кучу кода за раз, независимо от того, насколько аккуратно и элегантно он может быть написан. Разделение вещей на логические области позволяет мне свернуть код, который мне не нужен, для работы над кодом, который я делаюзаботиться о. Я не игнорирую плохо написанный код, нет смысла реорганизовывать его больше, чем он есть, и дополнительная «мета» организация является описательной, а не бессмысленной.
Теперь, когда я провел больше времени, работая на C ++, программируя больше непосредственно под Windows API, я чувствую, что хочу, чтобы поддержка регионов была так же хороша, как и для C #. Вы можете утверждать, что использование альтернативной библиотеки GUI сделает мой код проще или понятнее, устраняя тем самым необходимость убирать ненужный шум кода с экрана, но у меня есть другие причины не желать этого делать. Я достаточно опытен с моей клавиатурой и IDE, что развертывание / свертывание кода, разделенного на регионы, занимает менее доли секунды. Время, которое я экономлю на умственных способностях, пытаясь ограничить свое сознательное внимание только тем кодом, над которым я сейчас работаю, более чем стоит. Все они принадлежат одному классу / файлу, но не все они одновременно отображаются на моем экране.
Дело в том, что использование
#regions
для разделения и логического разделения вашего кода - это неплохая вещь, которую следует избегать любой ценой. Как указывает Эд, это не «запах кода». Если ваш код пахнет, вы можете быть уверены, что он исходит не из регионов, а из любого кода, который вы пытались похоронить в этих регионах. Если функция помогает вам быть более организованной или лучше писать код, тогда я говорю, используйте ее . Если это становится помехой или вы используете его неправильно, прекратите его использовать. Если худшее приходит к худшему, и вы вынуждены работать в команде с людьми, которые его используют, запомните сочетание клавиш, чтобы отключить выделение кода: Ctrl+ M, Ctrl+P, И перестань жаловаться. Иногда у меня возникает ощущение, что это еще один способ, которым те, кто хотят, чтобы их считали «настоящими», «хардкорными» программистами, любят пробовать и доказывать себя. Вам не лучше избегать регионов, чем избегать окраски синтаксиса. Это не делает вас более мачо разработчиком.Все это, как говорится, области в методе просто бессмыслица. Каждый раз, когда вы обнаружите, что хотите это сделать, вы должны использовать рефакторинг в отдельный метод. Никаких оправданий.
источник
Во-первых, я больше не могу терпеть термин «запах кода». Он используется слишком часто и часто используется людьми, которые не могут распознать хороший код, если он их укусил. В любом случае ...
Мне лично не нравится использовать много регионов. Это затрудняет доступ к коду, и код - это то, что меня интересует. Мне нравятся регионы, когда у меня есть большой кусок кода, к которому не нужно обращаться очень часто. Кроме того, они просто мешают мне, а такие регионы, как «Private Methods», «Public Methods» и т. Д., Просто сводят меня с ума. Они сродни комментариям разнообразия
i++ //increment i
.Я также хотел бы добавить, что использование регионов не может быть «антишаблоном», поскольку этот термин обычно используется для описания логики / шаблонов проектирования программы, а не макета текстового редактора. Это субъективно; используйте то, что работает для вас. Вы никогда не будете в конечном итоге с неуправляемой программой из-за чрезмерного использования регионов, что и есть анти-паттерны. :)
источник
Да регионы - это кодовый запах!
Я был бы рад видеть регионы, полностью удаленные из компилятора. Каждый разработчик придумывает собственную бессмысленную схему ухода, которая никогда не будет полезна другому программисту. У меня есть все, что связано с программистами, желающими украсить и украсить своего ребенка, не имеющими ничего общего с реальной ценностью.
Можете ли вы привести пример, когда вы говорите: «Боже, я бы хотел, чтобы мой коллега использовал здесь несколько регионов!»?
Несмотря на то, что я могу сконфигурировать свою среду IDE для автоматического расширения всех областей, они все еще являются болезненным для глаз и отвлекают от чтения реального кода.
Мне бы все равно, если все мои публичные методы объединены или нет. Поздравляем, вы знаете разницу между объявлением переменной и инициализацией, нет необходимости отображать ее в коде!
Ценный уход!
Кроме того, если ваш файл нуждается в «информационной архитектуре» посредством использования регионов, вы можете решить проблему с основной проблемой: ваш класс слишком велик! Разбить его на более мелкие части гораздо выгоднее, и при правильном выполнении добавляет истинную семантику / читабельность.
источник
Я лично использую регионы как способ группировать различные типы методов или частей кода вместе.
Таким образом, файл кода может выглядеть так при его открытии:
Я не ставлю регионы внутри методов. ИМХО, это признак запаха кода. Однажды я столкнулся с методом длиной более 1200 строк, в котором было 5 разных регионов. Это было страшное зрелище!
Если вы используете его как способ организации своего кода таким образом, чтобы ускорить поиск других разработчиков, я не думаю, что это признак проблем. Если вы используете его, чтобы скрыть строки кода внутри метода, я бы сказал, что пришло время переосмыслить этот метод.
источник
Использование
#region
блоков для чтения очень большого класса обычно является признаком нарушения принципа единой ответственности. Если они используются для группового поведения, то также вероятно, что класс делает слишком много (снова нарушая SRP).Придерживаясь мысли о «запахе кода»,
#region
блоки не являются запахами кода сами по себе, но вместо этого они больше «Febreze для кода» в том смысле, что они пытаются скрыть запахи. Хотя в прошлом я использовал их очень много, когда вы начинаете рефакторинг, вы начинаете видеть меньше, потому что в итоге они не скрывают много.источник
Ключевое слово здесь - «разумный». Трудно представить себе случай, когда размещение области внутри метода целесообразно; это слишком вероятно, чтобы скрывать код и лень. Тем не менее, могут быть веские причины иметь несколько областей здесь и там в своем коде.
Если есть много и много регионов, я думаю, что это запах кода. Регионы часто являются намеком на возможное место для будущего рефакторинга. Множество регионов означает, что кто-то на самом деле никогда не поймет намек.
При правильном использовании они дают хорошее промежуточное положение между структурой одного класса с множеством методов и структурой множества классов с несколькими методами в каждом. Они наиболее полезны, когда класс начинает приближаться к точке, в которой он должен быть подвергнут рефакторингу на несколько классов, но пока еще не совсем. Объединяя связанные методы вместе, я упрощаю выделение набора связанных методов в их собственный класс, если их количество продолжает расти. Например, если у меня есть класс, который приближается к 500 строкам кода, этот набор методов, использующий всего 200 строк кода, собранных вместе в одном регионе, вероятно, будет хорошим способом для рефакторинга каким-либо образом - и в этом другом регионе со 100 строками кода в его методы также могут быть хорошей целью.
Еще один способ, которым мне нравится использовать регионы, - это уменьшить один из негативных эффектов рефакторинга большого метода: множество маленьких, кратких, легко повторно используемых методов, которые читатель должен прокрутить, чтобы перейти к другому, в основном, не связанному методу. Регион может быть хорошим способом мета-инкапсуляции метода и его помощников для читателей, так что тот, кто работает с другим аспектом класса, может просто свернуть их и быстро отклонить эту часть кода. Конечно, это работает только в том случае, если ваши регионы действительно хорошо организованы и, по сути, используются в качестве другого способа документирования вашего кода.
В целом я нахожу регионы, которые помогают мне сохранять самоорганизацию, помогают «документировать» мой код и помогают мне находить места для рефакторинга гораздо раньше, чем если бы я не использовал регионы.
источник
В основном я использую регионы для классов серверов CRUD для организации различных типов операций. Даже тогда я мог бы с радостью обойтись без них.
Если широко использовать, это подняло бы красный флаг. Я буду в поисках классов, которые несут слишком большую ответственность.
По моему опыту, метод с сотнями строк кода, безусловно, запах.
источник
Мое эмпирическое правило: если у вас есть более 5 регионов в файле, это запах кода
То есть, возможно, было бы неплохо разграничить поле, методы, свойства и конструкторы, но если вы начинаете переносить каждый другой метод в свою область, то что-то серьезно неправильно
... и да, я был во многих проектах, где это имеет место, часто из-за плохих стандартов кодирования, генерации кода или того и другого. Давно быстро приходится переключать все контуры в визуальной студии, чтобы получить хороший обзор кода.
источник
РЕГИОНЫ ИХ ИСПОЛЬЗУЮТ
Я использовал их лично для событий интерфейса «ручного кодирования» ранее для приложений Windows Forms.
Однако в моей работе мы используем генератор кода для обработки SQL, и он автоматически использует регионы для сортировки методов выбора, обновления, удаления и т. Д.
Поэтому, хотя я не часто их использую, они идеально подходят для удаления больших кусков кода.
источник
Если у вас есть регионы В коде вы , конечно , есть проблема (запрещающий случай сгенерированного кода.) Собирает области в коде в основном говорят «реорганизовать это.»
Однако есть и другие случаи. Тот, который приходит на ум, что я сделал некоторое время назад: стол с парой тысяч предварительно рассчитанных предметов в нем. Это описание геометрии, за исключением ошибки в таблице, никогда не будет повода взглянуть на нее. Конечно, я мог бы получить данные из ресурса или тому подобного, но это исключило бы использование компилятора, чтобы облегчить его чтение.
источник
В недавнем проекте был метод 1700 линий с несколькими регионами, встроенными в него. Интересно то, что регионы отличают отдельные действия, которые были сделаны в рамках метода. Я был в состоянии сделать метод рефакторинга -> извлечения в каждой из областей, не влияя на функциональность кода.
В целом, регионы, используемые для скрытия кода котельной плиты, полезны. Я бы не советовал использовать регионы для сокрытия свойств, полей и тому подобного, потому что, если они слишком громоздки, чтобы на них можно было смотреть при работе внутри класса, это, вероятно, признак того, что класс должен быть дополнительно разбит. Но, как правило, если вы помещаете регион в метод, вам, вероятно, лучше извлечь другой метод, который объясняет, что происходит, чем перенос этого блока в регион.
источник
Можно ли использовать регионы в коде хорошего качества? Вероятно. Могу поспорить, что они, во многих случаях. Однако, мой личный опыт оставляет меня очень подозрительным - я видел регионы, которые почти исключительно злоупотребляли. Я бы сказал, что я измучен, но все же настроен оптимистично.
Я могу примерно разделить код, использующий регион, который я видел на сегодняшний день, на три категории:
Плохо разложенный код: большая часть кода, который я видел, использует регионы как инструмент факторинга для бедняков. Например, класс, который вырос до такой степени, что имеет смысл специализировать его для разных целей, вместо этого можно разделить на отдельные регионы, по одному для каждой цели.
Код, написанный с использованием неправильных библиотек, а иногда и неправильного языка, для проблемной области Часто, когда программист не использует правильный набор библиотек для проблемной области, вы увидите, что код становится невероятно многословным - с большим количеством маленьких вспомогательных функций. которые действительно не принадлежат (они, вероятно, принадлежат в их собственной библиотеке).
Кодекс, написанный студентами или недавними выпускниками. Некоторые программы и курсы, кажется, пытаются внушить студентам использование регионов для разных странных целей. Вы увидите, что регионы засоряют исходный код до такой степени, что отношение тегов регионов к строкам кода находится в диапазоне 1: 5 или хуже.
источник
Я бы сказал, что это «кодовый запах».
Анти-паттерны, как правило, являются фундаментальными структурными проблемами в программном обеспечении, тогда как регионы сами по себе просто вызывают неприятное поведение в редакторе. Использование областей на самом деле не является плохим по своей сути, но их частое использование, особенно для сокрытия фрагментов кода, может указывать на наличие других, независимых и более серьезных проблем, происходящих в других местах.
источник
Я использую регионы только для одного (по крайней мере, я не могу думать о других местах, где я их использую): группировать юнит-тесты для метода.
У меня обычно есть один тестовый класс на класс, а затем группирую модульные тесты для каждого метода, используя регионы, которые имеют имя метода. Не уверен, что это запах кода или что-то в этом роде, но поскольку основная идея заключается в том, что модульные тесты не нужно менять, если они не ломаются, потому что что-то в коде изменилось, мне легче найти все тесты для конкретного метода. довольно быстро
Возможно, я использовал регионы для организации кода в прошлом, но я не помню, когда в последний раз это делал. Я придерживаюсь своих регионов в классах модульного тестирования, хотя.
источник
Я считаю, что это анти паттерн и, честно говоря, думаю, что они должны быть устранены. Но если вы находитесь в неудачной ситуации, работая в месте, где они являются стандартными, Visual Studio предлагает отличный инструмент для минимизации суммы, которую вы хотели бы вызвать рвотой каждый раз, когда вы видите регион, который я ненавижу #Regions
Этот плагин максимально увеличит размер шрифта в регионах. Они также будут расширены, поэтому вам не придется нажимать Ctrl + M + L, чтобы открыть все регионы. Это не исправляет эту форму рака кода, но делает ее переносимой.
источник
Я использую регионы, чтобы содержать каждую комбинацию видимости и типа элемента. Так что все частные функции уходят в регион и т. Д.
Причина, по которой я это делаю, не в том, чтобы я мог сложить код. Это потому, что у меня есть скрипт моего редактора, так что я могу вставить, скажем, ссылку на прокси:
в код, и каждая часть аккуратно заправлена в соответствующий регион.
В этом случае макрос проанализирует мой проект, выдаст список прокси-серверов и введет код, который я хочу. Мой курсор даже не двигается.
В начале изучения C # я рассматривал использование регионов для сохранения общей общности, но это предложение типа «хит и мисс», потому что это не отношения один-к-одному во все времена. Кто хочет беспокоиться о члене, используемом двумя регионами, или даже начать разбивать вещи на этих условиях.
Единственный другой тип сегрегации - это методы. Я разбиваю методы на Команды, Функции и Обработчики, поэтому у меня будет область для общих, частных и т. Д. Команд и т. Д.
Это дает мне детализацию, но это последовательная, однозначная детализация, на которую я могу положиться.
источник
Регионы являются выражениями препроцессора - другими словами, они обрабатываются как комментарии и в основном игнорируются компилятором. Это чисто визуальный инструмент, используемый в Visual Studio. Поэтому #region на самом деле не является запахом кода, потому что это просто не код. Запах кода - это, скорее, метод из 800 строк, в который встроено много разных функций и т. Д. Итак, если вы видите 10 областей в одном методе - он, вероятно, используется, чтобы скрыть запах кода. Сказав, что я видел, как они используются чрезвычайно эффективно, чтобы сделать класс более приятным для глаз и более удобным для навигации - в очень хорошо написанном и структурированном классе тоже!
источник
Регионы были изящной организационной идеей, но не смогли учесть некоторые тенденции разработчиков хотеть переклассифицировать все и, как правило, не нужны в соответствии с большинством современных методов ООП ... они - «запах», в том смысле, что их использование часто указывает на что ваш класс / метод слишком велик и должен быть подвергнут рефакторингу, поскольку вы, вероятно, нарушаете "S" принципов SOLID ... но, как и любой запах, это не обязательно означает, что что-то идет не так.
Регионы служат большей функциональности в функциональном коде, чем в объектно-ориентированном коде, IMO, где у вас есть длинные функции последовательных данных, которые имеет смысл разбивать, но были случаи, когда я лично использовал их в c #, и они почти всегда сосредоточьтесь на коде, который вам не нужен / на который вы не хотите смотреть. Для меня это обычно были необработанные строковые константы SQL в базе кода, используемой для NPoco или его вариантов. Если вы на самом деле не заботитесь о том, как данные поступают для заполнения объекта POCO через ваш ORM, смотреть на них было совершенно бессмысленно ... и если вам все равно, эй, просто расширяйте регион и BAM! 150+ строк сложного SQL-запроса для вашего удобства просмотра.
источник