Является ли распространенным использование частичных классов для достижения «модульности»?

24

Недавно я столкнулся с ситуацией в нашей кодовой базе, когда другая команда создала «класс бога», содержащий около 800 методов, разделенных на 135 файлов как частичный класс.

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

Это обычная практика или в любом случае хорошая идея? Я склонен предпринять немедленные шаги, чтобы сбить этого зверя (или, по крайней мере, предотвратить его дальнейшее развитие), но я готов поверить, что я неправ

Джошуа Смит
источник
6
убить его огнем! А если серьезно, может ли другая команда предоставить какие-либо цитаты для этой предполагаемой общей практики?
MattDavey
1
Никто. Я уверен, что они курят, но я пытаюсь сделать все возможное, прежде чем уронить молот.
Джошуа Смит
Каковы их причины не делать это все время?
Джеффо
3
Попросите их описать в одном предложении, что общего между 800 методами в 135 файлах. Должна быть возможность ответить на это для любого вменяемого и разумного класса.
Carson63000
3
@ Carson63000 "Он выполняет все необходимые функции проекта." есть твое одно предложение.
Ryathal

Ответы:

39

Это ни в коем случае не хорошая идея.

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

Посмотрите на это так: если класс бога с 800 методами в одном файле, где вы знаете, где все находится, это плохо - и я думаю, что все согласятся, что это так - тогда как класс бога с 800 методами распределить по 135 файлам, где вы не знаете, где все может быть хорошо?

Мейсон Уилер
источник
1
Я в основном согласен, но я думаю, что могут быть редкие случаи, которые partialмогут быть полезны даже без сгенерированного кода. Может быть, когда у вас есть что-то вроде вложенного класса?
svick
1
@svick: Частичные занятия интересны, но обычно не нужны. Я не уверен, почему разделение класса на отдельные файлы было бы полезно, когда есть вложенные классы. Если вам не нужен вложенный класс в его собственном физическом файле. В этом случае ... maaaaybe все в порядке. ;)
FrustratedWithFormsDesigner
5
Я иногда использую частичные классы для явных реализаций интерфейса - особенно что-то вроде System.IConvertible. Каким-то образом кажется чище, чем помещать массивный # регион в моем классе.
MattDavey
1
Вложенный комментарий класса - действительно хорошая идея, я даже не думал об этом. Хотя ... это больше связано с организацией, чем с модульностью
Шелдон Варкентин
1
«Частичные классы существуют, чтобы помочь дизайнеру форм». Правильно в общем, но я бы добавил "... и другие генераторы кода". Я согласен с остальным вашим ответом;)
Сайлас
14

Итак, вопрос был:

Это обычная практика или в любом случае хорошая идея?

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

Однако этот вопрос - красная сельдь для действительно важной части, которая была пропущена; поскольку ФП также может сказать следующее о ситуации:

(...) Хотя моя внутренняя реакция состояла в том, чтобы убить его с орбиты, они настаивают ...

(...) Я склонен предпринять немедленные шаги, чтобы сбить этого зверя (или, по крайней мере, предотвратить его дальнейшее развитие), но я готов поверить, что ошибаюсь.

ПРИДЕРЖИ ЛОШАДЕЙ!

Это то, что заставило мой образно говоря монокль упасть в мою фигуративную чашку чая.

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

Что произойдет, если вы скажете команде, что их код отстой и отмахнулся ?

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

Какова текущая ситуация с кодовой базой? Работает? Тогда у вас возникнут большие проблемы с объяснением их клиентам, что их код по сути отстой . Не имеет значения, по каким причинам: пока он работает, большинство клиентов не заботятся о том, как организован код.

Также поставьте себя на их место, что они будут делать? Позвольте мне позабавить вас очень возможным исходом:

Член команды № 1: «Итак, этот парень говорит нам, что мы делали это неправильно в течение последних лет».

Участник команды № 2 и № 3: «Какой придурок».

Влиятельный член команды № 4: «Не беспокойтесь об этом, я просто пойду к руководству и оповестю об этом».

Посмотрите, что там сделал влиятельный член команды № 4 ? Он пошел в управление и уменьшил вашу карму в компании. Возможно, он американец-итальянец и говорит всем не беспокоиться об этом, но тогда я буду расистом по этому поводу.

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

Даже если вам удалось заставить группу людей подписать это, чтобы «преподать команде урок», помните, что вы делаете это с довольно умными людьми, которые, очевидно, добились определенных результатов. После того, как код будет переписан / реорганизован / обработан / с чем бы то ни было, и возникнут проблемы, вы будете привлечены к ответственности, так как вы были зачинщиком .

Состязаться с подобными ситуациями - это, в основном, игра «проиграл / проиграл», так как рискует стать порочным кругом игр с обвинениями. Это неоптимальный результат для этой ситуации. Даже если вы выиграете, вам вдруг передадут тот беспорядок, который сделал кто-то другой.

Есть и другие (очень зрелые) способы

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

  • Неосведомленные - Они действительно не знали, что есть другие пути, или просто не понимали. Младшие разработчики обычно подходят к этой категории, но не обязательно. (Если честно: я встречал начинающих разработчиков, которые были бы ярче этого.)
  • Стадо. Они знали лучшие приемы, чем частичные занятия, но не знали, что им позволено.
  • Циник. Им просто нравится утверждать, что частичные занятия лучше, чем ваша идея, просто для того, чтобы спорить. Это легко сделать в толпе, а не стоять перед толпой.
  • Ожог - по какой-то странной причине они не любят создавать новые классы, скорее всего, они воспринимают это как слишком сложное.
  • Время сокращено - они так заняты, что не могут исправить свой код.
  • Босс - Они думают: «Ну, это работает; так зачем?»
  • Иррациональное - хорошо, они просто сумасшедшие.

В книге приводится список стратегий и т. Д., Но в случае ОП это вопрос убеждения. Быть сильным с фактами об анти-паттерне недостаточно.

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

  • Что именно делает их класс бога?
  • У них возникли проблемы? У них есть ошибки? Предлагайте вменяемые исправления, не сообщая им об этом.
  • Если вы пользователь этого божьего класса в качестве API: есть ли более простые способы использования кода, чем использование всего этого? Предложите более простые примеры, посмотрите, как они реагируют.
  • Можете ли вы переключить некоторые функции с другой, без необходимости писать функцию?
  • Они нуждаются в некотором обучении? Можете ли вы убедить руководство дать ему это сделать или провести ланч-встречи о моделях и практиках?

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

Spoike
источник
Это очень проницательный ответ. Если вы новый разработчик, вы должны это понимать. Большинство опытных разработчиков осознают это через несколько лет, а некоторые никогда не понимают
FishySwede
6

Страница MSDN Partial Classes and Methods предлагает две ситуации для использования частичных классов:
1. Разделить гигантский класс на несколько отдельных файлов.
2. Иметь место для размещения автоматически сгенерированного исходного кода.

2 интенсивно используется Visual Studio (например, для файлов aspx и для winforms). Это разумное использование частичных классов.

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

Хотя если вы можете разумно разделить класс на отдельные файлы для работы с разными пользователями, разве вы не можете просто разделить его на отдельные классы?

Брайан
источник
+1 за «ты не можешь просто разделить его на отдельные классы?». Это именно то, что мы предлагаем. Похоже на здравый смысл, что это должно было быть сделано изначально.
Джошуа Смит
4

Таким образом, в конце концов, они делают нормальную процедурную разработку без какого-либо ООП. У них есть одно глобальное пространство имен со всеми методами, переменными и так далее.

Либо убедите их, что они делают это неправильно, либо убирайтесь отсюда.

Euphoric
источник
1

Служебный класс содержит методы, которые не могут быть разумно объединены с другими методами для создания класса. Если у вас есть более 800 методов, разделенных на 135 файлов, вероятно, кому-то удалось найти некоторые распространенные методы ...

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

Даже если у вас есть 800 в основном несвязанных методов, решение - это не один большой класс и множество файлов. Решением является пространство имен, несколько подпространств имен и множество маленьких классов. Это немного больше работы (вы должны придумать имя для класса, а также метод). Но это сделает вашу жизнь проще, когда придет время для очистки этого беспорядка, а между тем это облегчит использование intellisense (т. Е. Поможет определить, где метод должен его использовать).

И нет, это не часто (больше файлов, чем количество бесплатных функций).

jmoreno
источник
0

Мне это совсем не нравится. Однако, возможно, частичные классы имели смысл для разработчиков во время разработки, потому что это позволяло одновременно разрабатывать это большое количество методов, особенно если между ними нет большой зависимости.

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

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

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

Без шансов
источник
0

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

Ryathal
источник
3
Реорганизация процедурного кода в ОО, как правило, имеет эту проблему - я думаю, что исправить это будет огромной задачей и научить команду правильно кодировать, даже громаднее, кроме того, Джошуа будет обвинен во всем, что произойдет в течение следующего года (и после него). ) если он убедит их в рефакторинге. Вот почему никто никогда не настаивает на таких рефакторингах слишком сильно (по крайней мере, когда они увидят результаты). Кроме того, если вы считаете, что это хороший дизайн - хорошо - вернитесь к этому ответу через 5 лет и дайте нам знать, что вы думаете тогда (кажется, я переучиваю все, что я знаю о дизайне каждые 5 лет или около того).
Билл К
@BillK, если вы подождете десять лет, то, что вы знаете, вероятно, будет текущей философией дизайна "in".
Ryathal
135 файлов обычно группируют связанные методы, но это (для меня) все еще не делает это хорошей идеей. Я хочу испытать эту систему, но заглушка / издевательство над гидрой с 800 методами будет ужасной болью в заднице.
Джошуа Смит
@Ryathal - это не то, что «внутри», это то, что вы считаете хорошим дизайном (по уважительным причинам), а затем, когда вы практикуетесь и совершенствуетесь, вы понимаете, что это просто не такая хорошая идея, как вы думали. Кажется, что это происходит каждые 5 лет или около того, и как только я понял, что это умерило мой ответ на комментарии некоторых людей, потому что я понимаю, что они на самом деле отличные дизайнеры, которые (как и все мы) находятся в процессе постоянного совершенствования нашей практики. Единственный программист, о котором я бы беспокоился, это тот, кто не думал, что сможет улучшить код, написанный 5 лет назад.
Билл К
0

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

Шон МакДирмид
источник