#Regions - это антипаттерн или запах кода?


267

C # позволяет использовать ключевые слова #region/, #endregionчтобы сделать области кода разборными в редакторе. Всякий раз, когда я делаю это, я делаю это, чтобы скрыть большие куски кода, которые, вероятно, могут быть преобразованы в другие классы или методы. Например, я видел методы, которые содержат 500 строк кода с 3 или 4 областями, просто чтобы сделать его управляемым.

Таким образом, разумное использование регионов является признаком проблемы? Мне кажется, так оно и есть.


9
К вашему сведению: CodeMap в значительной степени устраняет потребности регионов. visualstudiogallery.msdn.microsoft.com/… - нажмите, и вы попадете в метод / атрибут / что угодно. Я использую его каждый день, и это удивительно, насколько вы выигрываете в производительности и в познавательном плане. Вы получаете намного более ясное представление о птичьем полете из класса.

7
Кто-нибудь может сделать это вики? На этот вопрос нет правильного или неправильного ответа (ну, в пределах разумного), он почти полностью субъективен.
Эд С.

6
За что это стоит, Джефф Этвуд их ненавидит . Он утверждает, что они скрывают плохой код.
Брайан

3
Кодовый запах - это разработчик, который не принимает душ и не использует дезодорант!
Марко

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

Ответы:


285

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

Поскольку:

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

регионы - это анти-паттерны. Они требуют больше работы, которая не повышает качество или удобочитаемость кода, не уменьшает количество ошибок и может только усложнить код для рефакторинга.

Не используйте регионы внутри методов; вместо этого рефакторинг

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

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

Использование регионов в этом случае также может усложнить рефакторинг. Представь, что у тебя есть:

private void DoSomething()
{
    var data = LoadData();
    #region Work with database
    var verification = VerifySomething();
    if (!verification)
    {
        throw new DataCorruptedException();
    }

    Do(data);
    DoSomethingElse(data);
    #endregion

    #region Audit
    var auditEngine = InitializeAuditEngine();
    auditEngine.Submit(data);
    #endregion
}

Свернуть первую область, чтобы сконцентрироваться на второй, не только рискованно: мы можем легко забыть об исключении, останавливающем поток ( returnвместо него может быть предложено защитное предложение , которое еще труднее обнаружить), но также возникнет проблема если код должен быть реорганизован таким образом:

private void DoSomething()
{
    var data = LoadData();
    #region Work with database
    var verification = VerifySomething();
    var info = DoSomethingElse(data);

    if (verification)
    {
        Do(data);
    }

    #endregion

    #region Audit
    var auditEngine = InitializeAuditEngine(info);
    auditEngine.Submit(
        verification ? new AcceptedDataAudit(data) : new CorruptedDataAudit(data));
    #endregion
}

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

Другой случай, который я иногда вижу, это:

public void DoSomething(string a, int b)
{
    #region Validation of arguments
    if (a == null)
    {
        throw new ArgumentNullException("a");
    }

    if (b <= 0)
    {
        throw new ArgumentOutOfScopeException("b", ...);
    }
    #endregion

    #region Do real work
    ...
    #endregion
}

Соблазнительно использовать регионы, когда проверка аргументов начинает охватывать десятки LOC, но есть лучший способ решить эту проблему: тот, который используется исходным кодом .NET Framework:

public void DoSomething(string a, int b)
{
    if (a == null)
    {
        throw new ArgumentNullException("a");
    }

    if (b <= 0)
    {
        throw new ArgumentOutOfScopeException("b", ...);
    }

    InternalDoSomething(a, b);
}

private void InternalDoSomething(string a, int b)
{
    ...
}

Не используйте регионы вне методов для группировки

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

  • Другие люди используют регионы, чтобы скрыть множество похожих объектов . Например, если у вас есть класс с сотнями полей (который составляет не менее 500 строк кода, если вы подсчитываете комментарии и пробелы), у вас может возникнуть желание поместить эти поля в область, свернуть ее и забыть о них. Опять же, вы делаете это неправильно: с таким количеством полей в классе вам следует лучше подумать об использовании наследования или разбить объект на несколько объектов.

  • Наконец, некоторые люди испытывают желание использовать регионы для группировки связанных вещей : событие с его делегатом или метод, связанный с IO, с другими методами, связанными с IO, и т. Д. В первом случае это становится беспорядком, который трудно поддерживать читать и понимать Во втором случае лучшим дизайном, вероятно, будет создание нескольких классов.

Есть ли хорошее применение для регионов?

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

Думайте об этом как о goto. Тот факт, что язык или IDE поддерживает функцию, не означает, что она должна использоваться ежедневно. Правило StyleCop SA1124 ясно: вы не должны использовать регионы. Никогда.

Примеры

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

4 000 LOC монстр:

Недавно я где-то читал на сайте Programmers.SE, что, когда файл содержит слишком много usings (после выполнения команды «Удалить неиспользуемые использования»), это хороший признак того, что класс внутри этого файла делает слишком много. То же самое относится и к размеру самого файла.

Просматривая код, я наткнулся на 4 000 LOC-файлов. Оказалось, что автор этого кода просто копировал один и тот же 15-строчный метод сотни раз, слегка изменяя имена переменных и вызываемый метод. Простое регулярное выражение позволило обрезать файл с 4 000 LOC до 500 LOC, просто добавив несколько обобщений; Я почти уверен, что при более умном рефакторинге этот класс может быть сокращен до нескольких десятков строк.

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

Регион «До А», Регион «До Б»:

Другим отличным примером был метод инициализации монстра, который просто выполнял задачу 1, затем задачу 2, затем задачу 3 и т. Д. Было пять или шесть задач, которые были полностью независимыми, каждая из которых инициализировала что-то в классе контейнера. Все эти задачи были сгруппированы в один метод и сгруппированы по регионам.

Это имело одно преимущество:

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

Проблемы, с другой стороны, были множественными:

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

  • Метод было практически невозможно проверить. Как бы вы легко узнали, что метод, который делает двадцать вещей одновременно, делает их правильно?

Область полей, область свойств, область конструктора:

Рассмотренный код также содержал множество областей, объединяющих все поля вместе, все свойства вместе и т. Д. Это имело очевидную проблему: рост исходного кода.

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

Другая проблема заключается в том, что если вы будете делать это повсеместно, вы обнаружите, что создаете области из одного блока, что не имеет никакого смысла. Это было на самом деле в коде, который я рассмотрел, где было много #region Constructorсодержащих один конструктор.

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


13
Я думаю, что есть по крайней мере несколько оправданных вариантов использования #regions - например, свертывание охранных предложений (проверка входных параметров), которые, если их не свернуть, отвлекают от сути или «мяса» метода. Другой пример - обработка исключений на границах API; вы часто не хотите влиять на трассировку стека, вызывая другие методы для переноса исключения, поэтому у вас есть несколько строк кода для переноса и повторного отбрасывания. Это также часто нерелевантный код, и его можно смело свернуть.
Даниэль Б

9
Проверка в реальных условиях. Я видел много межрегиональных # областей, которые были полезны. Если у вас есть метод из нескольких сотен строк с вложенной управляющей логикой с десятками до сотен строк с некоторыми из них - слава богу, идиот, по крайней мере, поместил в регионы.
радарбоб

37
@radarbob: короче говоря, регионы полезны в дрянном коде, который не должен существовать в первую очередь.
Арсений Мурзенко

41
-1 (если бы у меня была репутация). Даже если члены вашего типа хорошо организованы и разделены, их может быть много. Регионы избавляют вас от необходимости прокручивать 10 или 12 свойств и связанных методов получения и установки только для того, чтобы перейти к методу, с которым вы хотите работать. Единственная альтернатива состоит в том, чтобы свернуть все ваши свойства по отдельности, что я не фанат. Широкомасштабные области отображения / скрытия функциональных возможностей чрезвычайно полезны. Я согласен насчет областей внутри метода.
Асад Саидуддин

14
Я категорически не согласен с таким ответом: код вони и регион не имеют ничего общего друг с другом. Если ваш код воняет, он будет вонять с регионами или без них. Я использую регионы, чтобы разделить свои классы на регионы. Обычно я придерживаюсь того же шаблона: открытые свойства, открытые методы, приватные поля, приватные методы. Это единственное использование, для которого у меня были бы регионы. Что-нибудь еще, вы, вероятно, нарушаете принцип SRP в своем коде.
Алексус

113

Для меня невероятно, сколько людей так страстно ненавидят регионы!

Я полностью согласен со многими из их возражений: засунуть код, #regionчтобы скрыть его от глаз, - это плохо. Разделение класса на то, #regionsкогда он должен быть подвергнут рефакторингу на отдельные классы, является очевидной ошибкой. Использование #regionвстраивания избыточной семантической информации, ну, в общем, избыточно.

Но ни одна из этих вещей не означает , что есть что - нибудь по существу неправильно с использованием областей в коде! Я могу только предположить, что большинство людей возражают против того, что они работали в командах, где другие склонны неправильно использовать такие возможности IDE, как эта. Я могу позволить себе роскошь работать в начальной школе, и я ценю то, как регионы помогли организовать мой рабочий процесс. Может быть, это мое навязчивое компульсивное расстройство, но мне не нравится видеть на экране кучу кода за раз, независимо от того, насколько аккуратно и элегантно он может быть написан. Разделение вещей на логические области позволяет мне свернуть код, который мне не нужен, для работы над кодом, который я делаюзаботиться о. Я не игнорирую плохо написанный код, нет смысла реорганизовывать его больше, чем он есть, и дополнительная «мета» организация является описательной, а не бессмысленной.

Теперь, когда я провел больше времени, работая на C ++, программируя больше непосредственно под Windows API, я чувствую, что хочу, чтобы поддержка регионов была так же хороша, как и для C #. Вы можете утверждать, что использование альтернативной библиотеки GUI сделает мой код проще или понятнее, устраняя тем самым необходимость убирать ненужный шум кода с экрана, но у меня есть другие причины не желать этого делать. Я достаточно опытен с моей клавиатурой и IDE, что развертывание / свертывание кода, разделенного на регионы, занимает менее доли секунды. Время, которое я экономлю на умственных способностях, пытаясь ограничить свое сознательное внимание только тем кодом, над которым я сейчас работаю, более чем стоит. Все они принадлежат одному классу / файлу, но не все они одновременно отображаются на моем экране.

Дело в том, что использование #regionsдля разделения и логического разделения вашего кода - это неплохая вещь, которую следует избегать любой ценой. Как указывает Эд, это не «запах кода». Если ваш код пахнет, вы можете быть уверены, что он исходит не из регионов, а из любого кода, который вы пытались похоронить в этих регионах. Если функция помогает вам быть более организованной или лучше писать код, тогда я говорю, используйте ее . Если это становится помехой или вы используете его неправильно, прекратите его использовать. Если худшее приходит к худшему, и вы вынуждены работать в команде с людьми, которые его используют, запомните сочетание клавиш, чтобы отключить выделение кода: Ctrl+ M, Ctrl+P, И перестань жаловаться. Иногда у меня возникает ощущение, что это еще один способ, которым те, кто хотят, чтобы их считали «настоящими», «хардкорными» программистами, любят пробовать и доказывать себя. Вам не лучше избегать регионов, чем избегать окраски синтаксиса. Это не делает вас более мачо разработчиком.

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


9
Хорошо сказано. Использование регионов для организации не более вредно, чем переключение в среде IDE «просмотра пробелов». Это личное предпочтение.
Джош

24
Работая над WPF с ViewModels, имеющими 10 или 20 свойств, которые просто обертывают свойства моей модели, я обожаю регионы - я могу просто убрать эти свойства в область (к ним никогда не нужно прикасаться) и следить за соответствующим кодом.
Кирк Бродхерст

4
Полностью согласен. В .NET 2.0 свойства имеют длину около 8-10 строк. Когда у вас есть более 20 свойств в классе, они занимают много места. Регионы идеально подходят для их разрушения.
Кристоф Клас

6
@Kristof: Как и свойства в .NET 4.0, которые выполняют простую проверку ввода. Автоматические свойства просто не были такими уж волшебными для моих целей.
Коди Грей

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

70

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

Мне лично не нравится использовать много регионов. Это затрудняет доступ к коду, и код - это то, что меня интересует. Мне нравятся регионы, когда у меня есть большой кусок кода, к которому не нужно обращаться очень часто. Кроме того, они просто мешают мне, а такие регионы, как «Private Methods», «Public Methods» и т. Д., Просто сводят меня с ума. Они сродни комментариям разнообразия i++ //increment i.

Я также хотел бы добавить, что использование регионов не может быть «антишаблоном», поскольку этот термин обычно используется для описания логики / шаблонов проектирования программы, а не макета текстового редактора. Это субъективно; используйте то, что работает для вас. Вы никогда не будете в конечном итоге с неуправляемой программой из-за чрезмерного использования регионов, что и есть анти-паттерны. :)


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

7
Ха-ха, я не хочу сказать, что термин «запах кода» не может быть использован точно. Это возможно, но я вижу, что в эти дни вокруг него так много всего, что моя немедленная реакция - просто раздражение, особенно когда речь идет о людях, которые на самом деле просто повторяют то, что слышат, не понимая этого или не думая критически. Утверждения типа «более 5 локальных переменных в функции - это запах кода» просто показывают, насколько мало у этого человека опыта.
Эд С.

13
Не уверен, что понимаю ваш комментарий о запахах кода. Запахи кода не указывают на проблему, просто может быть проблема.
Крейг

7
+1 за противостояние термину запах. Я сыт по горло, когда я увидел сообщение, утверждающее, что частные методы были запахом кода. Но в целом я не согласен с вашим отвращением к регионам. Я легко отвлекаюсь. На самом деле, мне бы понравилось, если бы VS имел режим VB4, где вы могли бы отображать только один метод за раз.
Джош

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

23

Да регионы - это кодовый запах!

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

Можете ли вы привести пример, когда вы говорите: «Боже, я бы хотел, чтобы мой коллега использовал здесь несколько регионов!»?

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

Мне бы все равно, если все мои публичные методы объединены или нет. Поздравляем, вы знаете разницу между объявлением переменной и инициализацией, нет необходимости отображать ее в коде!

Ценный уход!

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


Являются ли #regions частью компилятора? Я думал, что они были просто директивой к IDE, которую можно игнорировать.
Стив Рукутс

2
Компилятор должен будет игнорировать их при анализе вашего кода C #. Если бы он не игнорировал их, он бы бросил на них. Я имею в виду это так.
Joppe

1
«Можете ли вы вспомнить один пример, когда вы говорите:« Черт, я бы хотел, чтобы мой коллега использовал здесь некоторые регионы! »?» Да, очень сильно. Когда у меня есть класс с закрытыми методами и открытыми методами, я разбиваю их по регионам, потому что при рефакторинге открытых методов вам не обязательно трогать закрытый код и наоборот.
Anshul

Вы, очевидно, никогда не видели внешний код. Ооочень много раз регионы было бы замечательно видеть в стороннем коде. Несмотря на то, что код отстой, по крайней мере, было бы намного легче понять, если бы он был сгруппирован в некотором логическом смысле. Хотя, если их код не логичен, шансы на то, что регионы тоже не будут, вероятно, сделали бы это еще хуже. Хотя регионы хороши при правильном использовании.
Nickmccomb

15

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

Таким образом, файл кода может выглядеть так при его открытии:

  • Публичная недвижимость
  • Конструкторы
  • Методы сохранения
  • Редактировать методы
  • Методы частного помощника

Я не ставлю регионы внутри методов. ИМХО, это признак запаха кода. Однажды я столкнулся с методом длиной более 1200 строк, в котором было 5 разных регионов. Это было страшное зрелище!

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


14
Тьфу. Я знаю, что это субъективная тема, но человек, я действительно не могу выдержать эту схему. По моему опыту, добавленная «организация» совсем не помогает, а просто делает просмотр кода болью в шее. Я также предпочитаю группировать методы не только по модификатору доступа, но и по логической ответственности. Для открытого интерфейса я обычно группирую каждый метод / свойство вместе, но часто защищенный метод может вызывать частную вспомогательную функцию, и в этом случае я предпочитаю, чтобы вспомогательная функция (которая может использоваться только там) была выше или ниже метод, который вызывает это.
Эд С.

3
@ Эд С. - вот почему я сказал "может выглядеть". Это очень субъективно. Я не говорю, что каждый файл должен выглядеть так. Я был бы удивлен, если бы они сделали. Просто пример на сложную тему. :)
Тианна

О, я знаю, как я уже сказал; это субъективно. Все, что работает для вас / вашей команды. У меня просто есть эта схема, потому что она не работает (для меня), но я должен был поддерживать проект, который сделал именно это. Это сводило меня с ума.
Эд С.

3
@EdS. Так что зайдите в настройки в vs и отключите регионы. Задача решена.
Энди

Почему у ваших объектов есть методы сохранения? :(
TheCatWhisperer

10

Использование #regionблоков для чтения очень большого класса обычно является признаком нарушения принципа единой ответственности. Если они используются для группового поведения, то также вероятно, что класс делает слишком много (снова нарушая SRP).

Придерживаясь мысли о «запахе кода», #regionблоки не являются запахами кода сами по себе, но вместо этого они больше «Febreze для кода» в том смысле, что они пытаются скрыть запахи. Хотя в прошлом я использовал их очень много, когда вы начинаете рефакторинг, вы начинаете видеть меньше, потому что в итоге они не скрывают много.


5

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

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

При правильном использовании они дают хорошее промежуточное положение между структурой одного класса с множеством методов и структурой множества классов с несколькими методами в каждом. Они наиболее полезны, когда класс начинает приближаться к точке, в которой он должен быть подвергнут рефакторингу на несколько классов, но пока еще не совсем. Объединяя связанные методы вместе, я упрощаю выделение набора связанных методов в их собственный класс, если их количество продолжает расти. Например, если у меня есть класс, который приближается к 500 строкам кода, этот набор методов, использующий всего 200 строк кода, собранных вместе в одном регионе, вероятно, будет хорошим способом для рефакторинга каким-либо образом - и в этом другом регионе со 100 строками кода в его методы также могут быть хорошей целью.

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

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


4

В основном я использую регионы для классов серверов CRUD для организации различных типов операций. Даже тогда я мог бы с радостью обойтись без них.

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

По моему опыту, метод с сотнями строк кода, безусловно, запах.


4

Мое эмпирическое правило: если у вас есть более 5 регионов в файле, это запах кода

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

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


4

РЕГИОНЫ ИХ ИСПОЛЬЗУЮТ

Я использовал их лично для событий интерфейса «ручного кодирования» ранее для приложений Windows Forms.

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

Поэтому, хотя я не часто их использую, они идеально подходят для удаления больших кусков кода.


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

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

4

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

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


1
Это лучший вариант использования для частичного класса с классом, хранящимся в отдельном файле, или, возможно, для вставленного IMyDataSource с реализацией HardcodedDataSource.
Брайан

3

В недавнем проекте был метод 1700 линий с несколькими регионами, встроенными в него. Интересно то, что регионы отличают отдельные действия, которые были сделаны в рамках метода. Я был в состоянии сделать метод рефакторинга -> извлечения в каждой из областей, не влияя на функциональность кода.

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


3

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

Я могу примерно разделить код, использующий регион, который я видел на сегодняшний день, на три категории:

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

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

  • Кодекс, написанный студентами или недавними выпускниками. Некоторые программы и курсы, кажется, пытаются внушить студентам использование регионов для разных странных целей. Вы увидите, что регионы засоряют исходный код до такой степени, что отношение тегов регионов к строкам кода находится в диапазоне 1: 5 или хуже.


3

Я бы сказал, что это «кодовый запах».

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



3

Я использую регионы только для одного (по крайней мере, я не могу думать о других местах, где я их использую): группировать юнит-тесты для метода.

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

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


1
У вас когда-нибудь были тесты, которые тестируют более одного метода?
Марси

Я не очень понимаю вопрос или что ты к нему стремишься. Ответ: нет, модульное тестирование всегда нацелено только на один метод или, скорее, на определенный аспект одного метода.
Анна Шуесслер

2

Я считаю, что это анти паттерн и, честно говоря, думаю, что они должны быть устранены. Но если вы находитесь в неудачной ситуации, работая в месте, где они являются стандартными, Visual Studio предлагает отличный инструмент для минимизации суммы, которую вы хотели бы вызвать рвотой каждый раз, когда вы видите регион, который я ненавижу #Regions

Этот плагин максимально увеличит размер шрифта в регионах. Они также будут расширены, поэтому вам не придется нажимать Ctrl + M + L, чтобы открыть все регионы. Это не исправляет эту форму рака кода, но делает ее переносимой.


0

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

Причина, по которой я это делаю, не в том, чтобы я мог сложить код. Это потому, что у меня есть скрипт моего редактора, так что я могу вставить, скажем, ссылку на прокси:

#region "private_static_members"
 /// <summary>
 /// cache for LauncherProxy
 /// </summary>
private static LauncherProxy _launcherProxy;
#endregion

#region "protected_const_properties"
protected LauncherProxy LauncherProxy{
  get{
    if(_launcherProxy==null) {
      if (!God.Iam.HasProxy(LauncherProxy.NAME)) {
        God.Iam.RegisterProxy(new LauncherProxy());
      }
      _launcherProxy=God.Iam.Proxy(LauncherProxy.NAME) as LauncherProxy;
    }
    return _launcherProxy;
  }
}
#endregion

в код, и каждая часть аккуратно заправлена ​​в соответствующий регион.

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

В начале изучения C # я рассматривал использование регионов для сохранения общей общности, но это предложение типа «хит и мисс», потому что это не отношения один-к-одному во все времена. Кто хочет беспокоиться о члене, используемом двумя регионами, или даже начать разбивать вещи на этих условиях.

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

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


-1, как только я получу 125 баллов, чтобы понизить. Вы добавляете ненужные строки кода. ПОЧЕМУ ПОЧЕМУ ПОЧЕМУ вы бы поместили область вокруг свойства ... if (God.Iam.AbusingRegions () == true) myName = "Mark"
DeadlyChambers

1
@DeadlyChambers Причина указана во втором абзаце - я использую макросы редактора для вставки общих шаблонов кода в файл, регионы помогают структурировать файл, чтобы схожие элементы были сгруппированы. Я не помещаю область вокруг единственного свойства, но все свойства попадают в назначенную область в зависимости от их атрибутов "protected_const_properties". Ты прочитал пост ??
Марк

1
Вы, вероятно, можете изменить это на: protected LauncherProxy LauncherProxy => God.Iam.GetOrAddProxy <LauncherProxy> (ref _launcherProxy); и, таким образом, вам сейчас не нужен регион. Также _launcherProxy может быть переименован в _launcherProxyCache, поэтому вам не нужны ни регион, ни комментарии.
аэрозон

0

Регионы являются выражениями препроцессора - другими словами, они обрабатываются как комментарии и в основном игнорируются компилятором. Это чисто визуальный инструмент, используемый в Visual Studio. Поэтому #region на самом деле не является запахом кода, потому что это просто не код. Запах кода - это, скорее, метод из 800 строк, в который встроено много разных функций и т. Д. Итак, если вы видите 10 областей в одном методе - он, вероятно, используется, чтобы скрыть запах кода. Сказав, что я видел, как они используются чрезвычайно эффективно, чтобы сделать класс более приятным для глаз и более удобным для навигации - в очень хорошо написанном и структурированном классе тоже!


0

Регионы были изящной организационной идеей, но не смогли учесть некоторые тенденции разработчиков хотеть переклассифицировать все и, как правило, не нужны в соответствии с большинством современных методов ООП ... они - «запах», в том смысле, что их использование часто указывает на что ваш класс / метод слишком велик и должен быть подвергнут рефакторингу, поскольку вы, вероятно, нарушаете "S" принципов SOLID ... но, как и любой запах, это не обязательно означает, что что-то идет не так.

Регионы служат большей функциональности в функциональном коде, чем в объектно-ориентированном коде, IMO, где у вас есть длинные функции последовательных данных, которые имеет смысл разбивать, но были случаи, когда я лично использовал их в c #, и они почти всегда сосредоточьтесь на коде, который вам не нужен / на который вы не хотите смотреть. Для меня это обычно были необработанные строковые константы SQL в базе кода, используемой для NPoco или его вариантов. Если вы на самом деле не заботитесь о том, как данные поступают для заполнения объекта POCO через ваш ORM, смотреть на них было совершенно бессмысленно ... и если вам все равно, эй, просто расширяйте регион и BAM! 150+ строк сложного SQL-запроса для вашего удобства просмотра.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.