Я видел этот поток
Если класс "Утилит" является злым, куда я помещаю свой общий код?
и мысль, почему служебные классы являются злыми?
Позволяет говорят, что у меня есть модель предметной области, которая является десятками классов глубоко. Я должен смочь к xml-ify экземплярам. Я делаю toXml метод на родителе? Я делаю класс помощника MyDomainXmlUtility.toXml? Это - случай, где бизнес-потребность охватывает всю модель предметной области - это действительно принадлежит как метод экземпляра? Что относительно того, если существует набор вспомогательных методов на xml функциональности приложения?
Служебные классы - это не совсем зло, но они могут нарушать принципы, составляющие хороший объектно-ориентированный дизайн. В хорошем объектно-ориентированном дизайне большинство классов должно представлять один объект со всеми его атрибутами и операциями. Если вы оперируете чем-то, этот метод, вероятно, должен быть его членом.
Однако бывают случаи, когда вы можете использовать служебные классы для группировки нескольких методов вместе - примером является класс java.util.Collections
, который предоставляет ряд утилит, которые можно использовать на любых Коллекция Java. Они не относятся к одному конкретному типу Коллекции, а вместо этого реализуют алгоритмы, которые можно использовать в любой Коллекции.
На самом деле, что вам нужно сделать, это подумать о своем дизайне и определить, где наиболее целесообразно разместить методы. Обычно это операции внутри класса. Однако иногда это действительно служебный класс. Однако, когда вы используете служебный класс, не просто добавляйте в него случайные методы, вместо этого организуйте методы по назначению и функциональности.
Утилитарные классы проблематичны, потому что они не могут сгруппировать обязанности с данными, которые их поддерживают.
Однако они чрезвычайно полезны, и я постоянно строю их либо как постоянные конструкции, либо как ступеньки во время более тщательного рефакторинга.
С точки зрения Чистый код служебные классы нарушают единую ответственность и принцип открытого-закрытого. У них есть множество причин для изменения, и они по замыслу не расширяемы. Они действительно должны существовать только во время рефакторинга как промежуточный мусор.
Служебные классы плохи, потому что они означают, что вы были слишком ленивы, чтобы придумать лучшее имя для класса :)
При этом, как говорится, я ленив. Иногда вам просто нужно закончить работу, а в голове ничего нет… вот тогда-то и начинают появляться "служебные" классы.
Очень легко обозначить что-либо как служебную программу просто потому, что разработчик не мог придумать подходящее место для размещения кода. Настоящих «утилит» часто бывает мало.
Как правило, я обычно сохраняю код в пакете, в котором он используется впервые, а затем выполняю рефакторинг только в более общее место, если обнаруживаю, что позже он действительно понадобится в другом месте. Единственное исключение - если у меня уже есть пакет, который выполняет аналогичные / связанные функции, и код лучше всего подходит для него.
Могут быть полезны служебные классы, содержащие статические методы без сохранения состояния. Часто их очень легко протестировать.
Я думаю, что общее мнение таково, что утилитарные классы не являются злом как таковым . Вы просто должны использовать их разумно:
Проектируйте статические методы утилит так, чтобы они были общими и многократно используемыми. Убедитесь, что они не имеют статических свойств, т.е. нет статических переменных.
Если у вас много вспомогательных методов, разделите их по классам таким образом, чтобы разработчикам было легко их найти.
Не используйте служебные классы там, где статические методы или методы экземпляра в доменном классе были бы лучшим решением. Например, подумайте, какие методы в абстрактном базовом классе или инстанцируемом вспомогательном классе были бы лучшим решением.
Для Java 8 и далее "методы по умолчанию" в интерфейсе могут быть лучшим вариантом, чем утилитарные классы.
Другой способ взглянуть на этот вопрос - заметить, что в процитированном вопросе "Если утилитарные классы - "зло"" - это аргумент соломинки. Это как если бы я спросил:
"Если свиньи умеют летать, должен ли я носить с собой зонтик?".
В вышеприведенном вопросе я не говорю, что свиньи могут летать ... или что я согласен с предложением, что они могут летать.
Типичные "xyz - зло" заявления - это риторические приемы, которые призваны заставить вас задуматься, представив экстремальную точку зрения. Они редко (если вообще когда-либо) воспринимаются как утверждения буквальных фактов.
Я полагаю, что он начинает превращаться в зло, когда
1) Он становится слишком большим (просто сгруппируйте их в значимые категории в этом случае).
2) Присутствуют методы, которые не должны быть статическими
Но пока эти условия не выполняются, я думаю, что они очень полезны.
Когда я не могу добавить метод к классу (скажем, Учетная запись
заблокирована от изменений младшими разработчиками), я просто добавляю несколько статических методов в свои Вот такой класс утилит:
public static int method01_Account(Object o, String... args) {
Account acc = (Account)o;
...
return acc.getInt();
}