Чи #regions протизапальний або кодовий запах?


264

C # дозволяє використовувати #region/ #endregionключові слова, щоб зробити області коду збірними в редакторі. Кожного разу, коли я це роблю, щоб приховати великі фрагменти коду, які, ймовірно, можуть бути перероблені на інші класи чи методи. Наприклад, я бачив методи, які містять 500 рядків коду з 3 або 4 регіонами, щоб зробити його керованим.

Тож чи розумне використання регіонів є ознакою неприємностей? Мені, здається, так і є.


9
FYI: CodeMap значною мірою усуває потреби в регіонах. visualstudiogallery.msdn.microsoft.com/… - Клацніть, і ви перейдете до методу / атрибута / будь-якого іншого. Я використовую його щодня, і дивно, скільки ви набираєте продуктивність і в пізнавальному плані. Ви отримуєте набагато чіткіший "погляд з пташиного польоту" класу.

7
Хтось може зробити це вікі? Немає правильної чи неправильної відповіді на це запитання (ну, в межах розуму), це майже повністю суб’єктивно.
Ред С.

6
За що це варто, Джефф Етвуд ненавидить їх . Він стверджує, що вони приховують поганий код.
Брайан

3
Кодовий запах - це розробник, який не душа і не використовує дезодорант!
marko

5
Ретельно складені регіони з смердючим кодом - це те, що кілька стискань Фетрізе робить на хрусткому дивані. Це робить його нестерпним, поки ви не знайдете (час) грошей для його заміни.
Ньютопський

Відповіді:


284

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

З моменту:

Антидіаграма (або антипаттерн) - це модель, що використовується в соціальних або ділових операціях або інженерії програмного забезпечення, яка може широко застосовуватися, але є неефективною та / або контрпродуктивною на практиці

регіони є анти-моделями. Вони потребують більшої роботи, яка не підвищує якість чи читабельність коду, що не зменшує кількість помилок, і це може лише зробити код більш складним для рефактора.

Не використовуйте регіони в методах; натомість рефактор

Методи повинні бути короткими . Якщо в методі є лише десять рядків, ви, ймовірно, не використовували б регіони, щоб приховати п'ять з них, працюючи над іншими п'ятьма.

Також кожен метод повинен робити одне і одне єдине . Регіони, навпаки, покликані розділяти різні речі . Якщо ваш метод робить 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 (після виконання команди "Видалити невикористані користування"), це хороший знак, що клас у цьому файлі робить занадто багато. Те саме стосується розміру самого файлу.

Переглядаючи код, я натрапив на файл 4000 LOC. Виявилося, що автор цього коду просто копіював вставку того ж 15-рядкового методу сотні разів, трохи змінивши назви змінних та названий метод. Простий регулярний вираз дозволив обрізати файл від 4000 LOC до 500 LOC, лише додавши кілька загальних даних; Я майже впевнений, що при більш розумному рефакторингу цей клас може бути скорочений до кількох десятків рядків.

Використовуючи регіони, автор закликав себе ігнорувати той факт, що код неможливо підтримувати і погано записати, і сильно дублювати код замість рефактора.

Регіон "Зробіть", регіон "зробіть B":

Іншим чудовим прикладом був метод ініціалізації монстра, який просто робив завдання 1, потім завдання 2, потім завдання 3 і т. Д. Було п'ять-шість завдань, які були абсолютно незалежними, кожна з яких ініціалізувала щось у класі контейнерів. Усі ці завдання були згруповані в один метод і згруповані в регіони.

Це мала одну перевагу:

  • Метод був досить зрозумілий, щоб зрозуміти, переглядаючи назви регіонів. Якщо говорити, той самий метод, що відбудеться після відновлення, був би таким же зрозумілим, як і оригінал.

Проблем, з іншого боку, було багато:

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

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

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

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

Коли ви відкриєте файл і побачите величезний список полів, ви схильні спочатку перефактурувати клас, а потім працювати з кодом. У регіонах ви звикаєте згортати речі і забувати про них.

Інша проблема полягає в тому, що якщо ви зробите це скрізь, ви опинитеся, що створюєте одноблокові регіони, що не має сенсу. Це було насправді в коді, який я розглянув, де було багато #region Constructorмістять одного конструктора.

Нарешті, поля, властивості, конструктори тощо повинні вже бути в порядку . Якщо вони є, і вони відповідають умовам (константи, починаючи з великої літери тощо), вже зрозуміло, де на типі елементів зупиняється і починається інше, тому не потрібно чітко створювати регіони для цього.


13
Я думаю, що існує принаймні кілька захисних застосувань # -регіонів - наприклад, згортання охоронних застережень (перевірка вхідних параметрів), які, якщо їх не розпадати, відволікають від суті або "м'яса" методу. Інший приклад - обробка винятків на кордонах API; часто не хочеться впливати на слід стека, викликаючи інші методи завершення винятку, тому у вас є кілька рядків коду, щоб обернути та повторно вписати. Це також часто невідповідний код, і його можна сміливо згортати.
Даніель Б

9
Перевірка реальності. Я бачив безліч міжрегіональних # регіонів, які були корисними. Коли у вас є кілька сотень лінійних методів з вкладеною логікою управління з десятками до сотень рядків в деяких з них - подякуйте, ідіот, принаймні, покладений у регіонах.
radarbob

37
@radarbob: коротше кажучи, регіони корисні для шаленого коду, який не повинен існувати в першу чергу.
Арсеній Муренко

41
-1 (якби у мене була репутація). Навіть якщо члени вашого типу добре організовані та розділені, їх може бути багато. Регіони заощаджують вам, що вам доведеться прокручувати останні 10 або 12 властивостей, а також пов'язані з ними геттери та сетери лише для того, щоб перейти до методу, над яким ви хочете працювати. Єдина альтернатива - руйнувати всі ваші властивості окремо, що я не фанат. Вкрай корисні великі масштаби функціонування регіонів показу / приховування. Я погоджуюсь щодо регіональних методів.
Asad Saeeduddin

14
Я категорично не погоджуюся з цією відповіддю: Кодекс смердючого регіону не має нічого спільного. Якщо ваш код смердить, він смердить з регіонами або без них. Я використовую регіони, щоб поділити свої класи на регіони. Як правило, я дотримуюся тієї ж схеми: Публічні властивості, Публічні методи, Приватні поля, Приватні методи. Це єдине використання, яке я мав би для регіонів. Що б там не було, ви, мабуть, порушили головний код SRP у своєму коді.
Алекс

113

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

Я повністю погоджуюся з такою кількістю їхніх заперечень: Переміщення коду в a, #regionщоб приховати його від перегляду, - погана річ. Поділ класу на те, #regionsколи він повинен бути перероблений на окремі класи, очевидно, є помилкою. Використання #regionвбудовування зайвої смислової інформації є, ну, зайвим.

Але жодна з цих речей не означає , що є що - небудь по суті неправильно з використанням областей в коді! Я можу лише припустити, що заперечення більшості людей походять від роботи над командами, де інші схильні неправильно використовувати такі функції IDE. Я маю розкіш роботи первинним самим, і я ціную те, як регіони допомогли організувати мій робочий процес. Можливо, це мій нав’язливий нав'язливий розлад, але мені не подобається бачити на своєму екрані купу коду за один раз, незалежно від того, наскільки акуратно та елегантно це написано. Поділ речей на логічні регіони дозволяє мені згортати код, який мені не цікаво працювати над кодом, який я роблюпіклуватися про. Я не ігнорую погано написаний код, не має сенсу переробляти його більше, ніж є, а додаткова "мета" організація є описовою, а не безглуздою.

Тепер, коли я витратив більше часу на роботу в C ++, програмуючи більш безпосередньо на API Windows, я вважаю, що бажаю, щоб підтримка регіонів була такою ж доброю, як і для C #. Ви можете стверджувати, що використання альтернативної бібліотеки графічного інтерфейсу зробить мій код простішим чи зрозумілішим, тим самим позбавляючи від необхідності виводити з екрану невідповідний шум коду, але у мене є інші причини, коли цього не хочу робити. Я достатньо досвідчений зі своєю клавіатурою та 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

По-перше, я більше не можу терпіти термін "кодовий запах". Він використовується занадто часто і багато часу приділяє людям, які не могли розпізнати хороший код, якби він їх вкусив. Все одно ...

Мені особисто не подобається використовувати багато регіонів. Це ускладнює отримання коду, і цей код мене цікавить. Мені подобаються регіони, коли у мене є великий шматок коду, який не потрібно чіпати дуже часто. Крім того, вони, здається, заважають мені, а такі регіони, як "Приватні методи", "Публічні методи" тощо, просто зводить мене з розуму. Вони схожі на коментарі до сорту i++ //increment i.

Я також додав би, що використання регіонів насправді не може бути «анти-шаблоном», оскільки цей термін зазвичай використовується для опису логіки / дизайну моделей програми, а не для макета текстового редактора. Це суб'єктивно; використовувати те, що працює для вас. Ви ніколи не збираєтеся закінчувати нездійсненну програму через ваше надмірне використання регіонів, саме про це і є антидіапазон. :)


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

7
Ха-ха, я не хочу сказати, що термін "кодовий запах" не може вживатися точно. Це може, але я бачу, що це так багато кинуто в ці дні, що моя негайна реакція викликає просто роздратування, особливо коли це стосується людей, які насправді просто повторюють те, що вони чують, не розуміючи цього чи критично думаючи. Висловлювання на кшталт "більше ніж 5 локальних змінних у функції є запахом коду" просто показують, наскільки мало досвіду у цієї людини.
Ед С.

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

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

7
Просто хотілося прозвучити і сказати, що неправильне використання абсолютно хорошої метафори не повинно знецінювати метафору. "Кодовий запах" - це чудова метафора, яка моментально зрозуміла, легко запам'ятовується та легко використовується. Є ще багато місць, де застосування метафори "кодового запаху" все ще є найкращим способом отримати бал.
Ерік Кінг

23

Так, регіони - це кодовий запах!

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

Чи можете ви придумати один приклад, де ви хоч "боже, я хотів би, щоб мій колега використав тут деякі регіони!"

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

Мені б справді менше турбуватись, чи всі мої публічні методи зібрані разом чи ні. Вітаємо, що ви знаєте різницю між декларацією змінної та ініціалізацією, не потрібно відображати її в коді!

Безцінне догляд!

Крім того, якщо ваш файл потребує та "інформаційна архітектура", використовуючи регіони, ви можете боротися з основною проблемою: Ваш клас занадто великий! Розбиття його на більш дрібні частини набагато вигідніше і при правильному виконанні додає справжньої семантики / читабельності.


Чи є #regions частиною компілятора? Я подумав, що вони є лише директивою до IDE, яку можна ігнорувати.
Стів Рукуць

2
Компілятору потрібно було б ігнорувати їх під час аналізу вашого C # коду. Якщо вони не ігнорують їх, вони б накидалися на них. Я маю на увазі саме так.
Джоппе

1
"Ви можете придумати один приклад, де ви хоч" боже, я хотів би, щоб мій колега використав тут деякі регіони! " Так, дуже. Коли у мене є клас із приватними методами та публічними методами, я розбиваю їх у регіонах, тому що, коли рефакторинг публічних методів, не обов'язково торкатися приватного коду та навпаки.
Аншул

Ви, очевидно, ніколи не бачили стороннього коду. Sooo багато разів регіонів було б чудово бачити в коді, що передається на замовлення. Незважаючи на те, що код смокче, принаймні, було б набагато простіше зрозуміти, якби він згрупувався в якомусь логічному сенсі. Хоча, якби їх код не був логічним, шанси, що регіони не були б і тим, ймовірно, це погіршило б. Регіони чудово при правильному використанні.
Nickmccomb

15

Я особисто використовую регіони як спосіб групувати різні типи методів або частин коду разом.

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

  • Суспільні властивості
  • Конструктори
  • Методи збереження
  • Методи редагування
  • Приватні методи допомоги

Я не вкладаю регіони всередину методів. ІМХО, що є ознакою запаху коду. Я одного разу натрапив на метод, який був довжиною понад 1200 рядків і в ньому було 5 різних регіонів. Це було страшне видовище!

Якщо ви використовуєте його як спосіб впорядкування свого коду таким чином, щоб зробити пошук речі швидшим для інших дивідів, я не думаю, що це ознака неприємностей. Якщо ви використовуєте його для приховування рядків коду всередині методу, я б сказав, що настав час переосмислити цей метод.


14
Тьфу. Я знаю, що це суб'єктивна тема, але людино, я дійсно не витримую цієї схеми. На мій досвід, додана "організація" зовсім не допомагає, і це просто переглядає код, болі в шиї. Я також віддаю перевагу методам групування не лише за модифікатором доступу, але і за логічною відповідальністю. Для загальнодоступного інтерфейсу я зазвичай групую кожен метод / властивість разом, але часто захищений метод може викликати функцію приватного помічника, і в такому випадку я дуже віддаю перевагу функції помічника (яка може використовуватися лише там) вище або нижче метод, який викликає його.
Ред С.

3
@Ed S. - тому я сказав "може виглядати так". Це дуже суб’єктивно. Я не кажу, що кожен файл повинен виглядати так. Я був би здивований, якби вони. Просто приклад на складну тему. :)
Тяньна

О, я знаю, як я сказав; це суб'єктивно. Що б не працювало для вас / вашої команди. У мене це просто для цієї схеми, оскільки вона не працює (для мене), але мені довелося підтримувати проект, який зробив саме це. Це зводило мене з розуму.
Ред С.

3
@EdS. Тож перейдіть до своїх варіантів у порівнянні та вимкніть регіони. Проблема вирішена.
Енді

Чому у ваших об’єктів є методи збереження? :(
TheCatWhisperer

10

Використання #regionблоків для того, щоб зробити читальним дуже великий клас, як правило, є ознакою порушення принципу єдиної відповідальності. Якщо вони використовуються для групової поведінки, то ймовірно, що клас робить занадто багато (вкотре порушує SRP).

Дотримуючись лінійки думок "запах коду", #regionблоки не пахнуть кодом, а самі вони є "Febreze для коду", тому що вони намагаються приховати запахи. Хоча я використовував їх тонна в минулому, коли ви починаєте рефакторинг, ви починаєте бачити менше, оскільки вони в кінцевому рахунку не приховують багато.


5

Ключове слово тут - "розумний". Важко уявити випадок, коли розміщення області всередині методу є розумним; це занадто ймовірно, що приховування коду і лінь. Однак можуть бути вагомі причини того, що в коді є декілька регіонів.

Якщо регіонів багато і багато, я думаю, що це кодовий запах. Регіони часто натякають на можливе місце майбутнього рефакторингу. Багато регіонів означає, що хтось насправді ніколи не приймає підказки.

Використовувані з розумом, вони дають хороший середину між структурою єдиного класу з багатьма методами та структурою багатьох класів із лише кількома методами в кожному. Вони найкорисніші, коли клас починає наближатися до тієї точки, коли він повинен перетворитись на кілька класів, але ще не зовсім там. Групуючи пов'язані методи разом, я згодом полегшу витягнути набір пов'язаних методів у свій клас, якщо вони продовжують зростати. Наприклад, якщо у мене є клас, який наближається до 500 рядків коду, цей набір методів, що використовують 200 рядків коду, зібраних разом у регіоні, ймовірно, є хорошим елементом, яким би якимось чином не став рефактор - і той інший регіон із 100 рядками коду у своєму методи також можуть бути хорошою ціллю.

Ще один спосіб, який мені подобається використовувати у регіонах, - це зменшити один з негативних наслідків рефакторингу великого методу: безліч дрібних, стислих, легко використаних методів, через які читачеві доводиться прокручувати, щоб перейти до іншого, переважно неспорідненого методу. Регіон може бути хорошим способом метакапсуляції методу та його помічників для читачів, тому хтось, хто працює з іншим аспектом класу, може просто їх згортати і швидко відхиляти цю частину коду. Звичайно, це працює лише в тому випадку, якщо ваші регіони справді добре організовані і по суті використовуються як ще один спосіб документування вашого коду.

Загалом, я вважаю, що регіони допомагають мені організовуватися, допомагають "документувати" свій код і допомагають мені ловити місця для рефактора набагато швидше, ніж якщо я не використовую регіони.


4

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

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

На мій досвід, метод із сотнями рядків коду - це безумовно запах.


4

Моє правило: якщо у файлі більше 5 регіонів, це запах коду

Тобто, це може бути добре, щоб розмежувати поле, методи, властивості та конструктори, але якщо ви починаєте обгортати будь-який інший метод у власному регіоні, щось серйозно не так

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


4

РЕГІОНИ ВИКОРИСТОВУЮТЬ ЇХ

Я використовував їх особисто для інтерфейсу подій "кодування вручну" для програм Windows форм.

Однак у своїй роботі ми використовуємо генератор коду для обробки SQL, і він автоматично використовує регіони для сортування його методів вибору, оновлення, видалення тощо.

Тому, хоча я не використовую їх часто, вони ідеально підходять для видалення великих фрагментів коду.


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

У нас же регіони знаходяться всередині згенерованого коду, щоб полегшити його читання або налагодження (якщо потрібно).
Кен

4

Якщо у вас є код IN, у вас, безумовно, є проблеми (заборона випадку згенерованого коду.) Введення регіонів у код в основному говорить "refactor this".

Однак є й інші випадки. Той, що спадає на думку, що я робив деякий час назад: Таблиця з кількома тисячами попередньо обчислених елементів. Це опис геометрії, окрім помилки в таблиці, ніколи не буде приводу подивитися на це. Звичайно, я міг отримати дані з ресурсу чи подібного, але це не дозволить використовувати компілятор, щоб полегшити його читання.


1
Це кращий варіант використання для часткового класу, який зберігається в окремому файлі, або, можливо, введений IMyDataSource з реалізацією HardcodedDataSource.
Брайан Ботчер

3

У недавньому проекті був створений метод 1700 ліній із вбудованими кількома регіонами. Цікавим є те, що регіони розмежовували чіткі дії, які робляться в рамках методу. Мені вдалося зробити метод вилучення рефактора -> для кожної з областей, не впливаючи на функціональність коду.

Загалом, регіони, які використовуються для приховування коду пластини котла, корисні. Я б радив не використовувати регіони для приховування властивостей, полів тощо, тому що якщо вони занадто невмілі, щоб дивитись під час роботи в класі, це, мабуть, знак того, що клас слід додатково розбити. Але як важке правило, якщо ви вводите область в метод, вам, мабуть, буде краще витягнути інший метод, який пояснює, що відбувається, ніж загортання цього блоку в регіон.


3

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

Я можу приблизно поділити код, що використовує регіон, який я бачив на сьогодні на три категорії:

  • Код з поганим врахуванням: Більшість коду, який я бачив, використовує регіони як інструмент факторингу бідних людей. Наприклад, клас, який виріс до того, що має сенс спеціалізувати його для різних цілей, може бути замість цього розділений на окремі регіони, по одному для кожної мети.

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

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


3

Я б сказав, що це "кодовий запах".

Анти-шаблони, як правило, є основними структурними проблемами в програмному забезпеченні, тоді як регіони самі по собі викликають неприємну поведінку редактора. Використання регіонів насправді погано, але їх використання дуже багато, особливо для приховування фрагментів коду, може означати, що в інших місцях виникають інші, незалежні та більші проблеми.


@Andrew Grimm: так
whatsisname

3

Я використовую регіони лише для однієї речі (принаймні, я не можу придумати інші місця, якими я їх користуюся): щоб групувати одиничні тести методу.

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

Можливо, я використовував регіони для організації коду в минулому, але я не можу згадати востаннє, коли я це робив. Хоча я дотримуюся своїх регіонів в одиничних тестових класах.


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

Я не дуже розумію питання або на що ви це націлені. Відповідь: Ні, одиничний тест завжди орієнтований лише на один метод, а точніше на певний аспект одного методу.
Енн Шусслер

2

Я вважаю, що це анти-модель і, чесно кажучи, їх слід усунути. Але якщо ви потрапили в нещасну ситуацію, коли працюєте в тому місці, де вони є стандартною, Visual Studio пропонує приголомшливий інструмент для мінімізації кількості, яку ви хочете блювотати щоразу, коли побачите регіон Я ненавиджу # Регіони

Цей плагін максимум розміру шрифту в регіонах дійсно невеликий. Вони також будуть розширені, тому вам не доведеться натискати ctr + 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 балів, щоб перемогти. Ви додаєте непотрібні рядки коду. ЧОМУ ЧОМУ чому б ви поставили область навколо власності ... якщо (God.Iam.AbusingRegions () == true) myName = "Позначити"
DeadlyChambers

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

1
Ви можете, ймовірно, змінити це на: захищений LauncherProxy LauncherProxy => God.Iam.GetOrAddProxy <LauncherProxy> (ref _launcherProxy); і тому вам зараз не потрібен регіон. Також _launcherProxy можна перейменувати в _launcherProxyCache, тому вам не потрібен регіон, ані коментарі.
аерозон

0

Регіони - це препроцесорні вирази - іншими словами, вони трактуються як коментарі та в основному ігноруються компілятором. Вони є суто візуальним інструментом, який використовується у Visual Studio. Тому #region насправді не є кодовим запахом, тому що це просто не код. Запах коду - це скоріше метод 800 рядків, в який вкладено багато різних обов'язків тощо. Отже, якщо ви бачите 10 регіонів в одному методі - він, ймовірно, використовується для приховування запаху коду. Сказавши, що я бачив, як вони використовували надзвичайно ефективно, щоб зробити клас більш приємним для очей і більш навігаційним - і в дуже добре написаному та структурованому класі!


0

Регіони були чудовою організаційною ідеєю, але не змогли врахувати деякі тенденції розробників, які хочуть передати категоризацію всього, і взагалі непотрібні згідно з більшістю сучасних практик ООП ... вони "запах", в тому сенсі, що їх використання часто вказує що ваш клас / метод є занадто великим і його слід переробити, оскільки ви, ймовірно, порушуєте "S" принципів SOLID ... але, як і будь-який запах, це не обов'язково означає, що щось йде погано.

Регіони служать більш цільовим функціональним кодом, а не об'єктно-орієнтованим кодом, ІМО, де у вас є довгі функції послідовних даних, які має сенс розбивати, але були випадки, коли я особисто використовував їх у c #, і вони майже завжди зосередитися на коді, який вам не потрібно / хочете дивитись. Для мене це, як правило, сирі струнні константи SQL в кодовій базі, використовувані для NPoco або його варіантів. Якщо ви насправді не хвилюєтесь, як дані надходять для заповнення об'єкта POCO через ваш ORM, на це було зовсім безглуздо дивитися ... а якщо вам все-таки було важливо, ей, просто розгорніть регіон та BAM! 150+ рядків складного запиту SQL для задоволення від перегляду.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.