Категории или частичные классы: образец для устранения "божьего объекта" Запах кода?
Класс слишком большой и становится громоздким для работы. В Objective-C я хотел бы использовать Категории, чтобы разбить класс, но тогда: не будут ли категории просто делить дом, полный слишком большого количества мусора, на комнаты? Полагаю, тот же вопрос относится и к частичным классам в C#.
При каких условиях можно использовать категории для устранения запаха кода "слишком большого класса"? Когда это не правильно, и класс действительно должен быть "реструктурирован или разбит на более мелкие классы?"
4 ответа
Очень хороший принцип, на который можно сослаться, это принцип SOLID. В частности, буква "S" означает "Единая ответственность".
Принцип единой ответственности
понятие, что объект должен иметь только одну ответственность.
Когда классы становятся слишком большими, вероятно, у них слишком много обязанностей. Можете ли вы определить две или более обязанности в границах того, что делает класс? Если это так, разделите его на два или более классов. Затем вы можете объединить их обратно, используя фасад или составной шаблон.
Другими словами:
- код в вашем классе должен быть разбит на разные классы в соответствии с принципом единой ответственности
- исходный класс God становится составным или фасадным: он использует все новые классы, предоставляет те же методы остальной части системы, но не реализует никаких функциональных возможностей сам по себе, кроме "преобразования" вызовов God-класса старого стиля в SOLID звонки нового стиля.
Это означает, что регионы ничего не делают для решения вашей проблемы с объектно-ориентированной точки зрения. На самом деле, они на самом деле контрпродуктивны, поскольку способствуют скрытию проблемы.
Смотрите также эту статью Джеффа Этвуда:
http://www.codinghorror.com/blog/2008/07/the-problem-with-code-folding.html
Я должен признать, что я никогда не использовал Objective-C, но, конечно, я использовал C#.
Сказав это, частичные классы - это то же самое, что классы, разделяющие класс на несколько файлов, не уменьшают класс, а разделяют только на файлы. Использование класса будет таким же.
Поэтому я не согласен, что частичные классы решат эту проблему, они были изобретены в основном для других целей, таких как формы Windows, wpf, автоматически сгенерированный код. Они полезны также в других ситуациях, когда классы не могут быть логически разделены, но обычно их следует избегать.
Я думаю, что вы должны разделить свой класс на несколько классов, класс начинает пахнуть после 1k LOC (строк кода), даже если класс разделен на несколько файлов.
Используйте наследование или разделите класс на несколько классов, связанных полями и свойствами. В примере, представленном chemicalNova, я бы разбил его на несколько классов, а не на несколько файлов.
Я помню, когда я был новичком, у нас был этот класс богов "BusinessService" или что-то подобное. Каждый раз, когда кто-то блокировал его в TFS, вам не везло. Так что у меня возникла блестящая идея, почему бы нам не разбить ее на частичные занятия? В итоге мы получили что-то вроде "BusinessService1.cs" .. "BusinessService6.cs". Это был полный беспорядок и полное разочарование, чтобы найти, где вещи.
Я думаю, что каждый раз, когда вам нужно использовать частичный класс, это ошибка проектирования. Если Microsoft заставляет вас это делать (wpf, winforms и т. Д.) - это ошибка их дизайна.
Нет ничего плохого в разбиении класса на частичные. Это то, что немногие разработчики используют в своих интересах.
Лично мне нравится разбивать большие классы на партиалы, где деловая сторона каждого партиала имеет схожую функциональность, но только если во время разработки кажется, что указанный класс станет довольно большим. В противном случае я делю связанные функции на регионы.
Например, если у меня должен быть "UserService", который находится на уровне данных, я мог бы разделить его на несколько частей следующим образом:
UserServiceQueries.cs
UserServiceUpdates.cs
UserServiceInserts.cs
UserServiceLogicalFunctions.cs
..но они содержат частичные классы "UserService". Обычно я не часто использую ORM, так что это идеально для меня, потому что каждая часть связанной функциональности может стать довольно большой (очевидно, это базовый пример).
В заключение: воспользоваться тем, что поставляется. Если вы чувствуете запах кода из-за того, что у вас огромный класс... у вас есть только 2 варианта... переписать его или разбить на части (если он определенно должен быть таким большим).
Мое мнение в любом случае.