Это плохо? форма, чтобы иметь класс MiscUtilities? [закрыто]

13
задан Bad Request 20 August 2010 в 14:02
поделиться

14 ответов

Для языков, поддерживающих функции, такой класс, несомненно, является плохим тоном.

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

Конечно, здесь присутствует определенная доля личного стиля. Я не очень-то верю в классы, которые предоставляют все необходимое (даже C ++ std :: string , на мой вкус, немного перегружен) и предпочитаю иметь вспомогательные функции как отдельные функции. Облегчает обслуживание класса, заставляет общедоступный интерфейс быть полезным и эффективным, а с механизмами стиля утиной печати внешние функции могут использоваться в широком диапазоне типов без необходимости дублировать исходный текст или совместно использовать базовые классы и т. Д. (Часто высмеиваемые алгоритмы в стандартной библиотеке C ++ являются хорошей демонстрацией этого, хотя они и несовершенны и многословны.)

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

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

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

Я полагаю, что краткое изложение: нет.

2
ответ дан 1 December 2019 в 21:23
поделиться

Скорее всего, удобно.

Скорее всего, он может вырасти в страшного и сложного в обслуживании швейцарского армейского ракетопила и полировщика полов.

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

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

4
ответ дан 1 December 2019 в 21:23
поделиться

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

Примеры вещей в моем вспомогательном классе:

  1. hex2, hex4 и hex8 (принимают целочисленные параметры, кроме hex8, у которого есть целочисленные и uinteger вариации; все версии игнорируют биты более высокого порядка)
  2. байт (преобразовать 8 фунтов аргумента в байт)
  3. getSI, getUI, getSL, getUL (каждый принимает массив байтов и смещение и возвращает слово со знаком с прямым порядком байтов, слово без знака, 32-разрядное слово со знаком или 32-разрядное слово без знака при этом смещении
  4. putSI, putUI, putSL, putUL (принимает массив байтов, смещение и значение, которое нужно поместить туда в формате с прямым порядком байтов)
  5. hexArr (преобразует массив байтов или его часть в шестнадцатеричную строку)
  6. hexToArr (преобразует шестнадцатеричную строку в байтовый массив)
  7. Zap (из T как iDisposable) (принимает byref iDisposable; если не Nothing, удаляет его и устанавливает для него значение Nothing)

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

1
ответ дан 1 December 2019 в 21:23
поделиться

Ну, плохие служебные классы высмеиваются на TheDailyWTF :)

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

Один из подходов, который вы можете принять в зависимости от языка и т. Д., - это, возможно, переместить часть логики в расширения существующих объектов. Например, расширение класса String (здесь мы думаем на C #) с помощью метода, который пытается преобразовать строку в DateTime. Собственная библиотека расширений просто улучшает язык с помощью собственных небольших DSL вашего бизнеса.

1
ответ дан 1 December 2019 в 21:23
поделиться

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

0
ответ дан 1 December 2019 в 21:23
поделиться

Обычно у меня нет проблем с ними, хотя, как и со всеми вещами, ими можно злоупотреблять:

  • Они сильно разрастаются, так что большинство проблем, использующих класс, не t использовать 99% функций.
  • Они становятся очень большими, так что 90% функций не используются ни одной программой, которая все еще используется.
  • Часто они являются свалкой для функций, специфичных для одной области. Их следует сократить до использования аналогичного класса только программой в этой области. Часто эти функции лучше включать в соответствующие классы.
0
ответ дан 1 December 2019 в 21:23
поделиться

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

0
ответ дан 1 December 2019 в 21:23
поделиться

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

Я бы предпочел более объектно-ориентированный подход, который привел бы к расширяемости. Обязательно имейте класс Utilities, но внутри него поместите другие классы, которые расширяются до определенной функциональности. Например, Utilities.XML, Utilities.DataFunctions, Utilities.WhateverYouWant. Таким образом, вы можете расширить и в конечном итоге взять свой класс MiscUtilities из 20 функций и превратить его в библиотеку классов функций из 500.

Подобная библиотека классов может быть использована кем угодно и добавлена ​​кем угодно (с привилегиями) логически организованным способом.

1
ответ дан 1 December 2019 в 21:23
поделиться

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

Тем не менее, эти модули явно нарушают принципы объектно-ориентированного проектирования.

Итак, в настоящее время я называю модуль StuffIHaventRefactored, и все же с миром все в порядке.

0
ответ дан 1 December 2019 в 21:23
поделиться

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

Цитата из Эффективное 2-е издание Java, пункт 4: Обеспечьте неэкземплярность с помощью частного конструктора :

Иногда вы захотите написать класс, который представляет собой просто группу static и статические поля. Такие классы приобрели плохую репутацию, потому что некоторые люди злоупотребляют ими, чтобы не мыслить категориями объектов, но у них действительно есть допустимое использование . Их можно использовать для группировки связанных методов по примитивным значениям или массивам, как java.lang.Math или java.util.Arrays .Их также можно использовать для группировки статических методов, включая фабричные методы, для объектов, реализующих определенный интерфейс, в виде java.util.Collections . Наконец, их можно использовать для группировки методов в классе final вместо расширения класса.

В библиотеках Java есть много примеров таких служебных классов.


Краткое резюме

  • Предпочитайте хороший дизайн ООП, всегда
  • статические служебные классы имеют допустимое применение для групповых связанных методов на:
    • Примитивы (поскольку они не являются объектами)
    • Интерфейсы (поскольку они не могут иметь ничего конкретного собственного)
    • final классы (поскольку они не расширяемы)
  • Предпочитать хорошие организация, всегда
    • Группа служебных методов для SomeType - SomeType Utils или SomeType s
    • Избегайте одного большого служебного класса, который содержит различные несвязанные задачи по разным типам / концепциям
12
ответ дан 1 December 2019 в 21:23
поделиться

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

3
ответ дан 1 December 2019 в 21:23
поделиться

Утилитарные классы сами по себе неплохи. Иногда их можно (неправильно|ab|over)использовать, но у них есть свое место. Если у вас есть утилитарные методы для типов, которыми вы владеете, подумайте о переносе статических методов в соответствующие типы. Или создайте методы расширения.

Старайтесь избегать монолитного класса утилит - они могут быть статическими методами, но у них будет плохая связность. Разбейте большой набор несвязанных функций на более мелкие группы связанной функциональности, точно так же, как вы делаете это с "обычными" классами. Назовите их *Helper или *Utils, или как вам больше нравится. Но будьте последовательны и группируйте их вместе, возможно, в папке внутри проекта.

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

1
ответ дан 1 December 2019 в 21:23
поделиться

Я думаю, что неправильный недостаток такого класса состоит в том, что он нарушает принцип разделения ответственности . Обычно я создаю несколько классов «Helpers», содержащих широко используемые общедоступные статические методы, например ArrayHelpers для записи списков ArrayLists в файлы и DatesHelper для преобразования дат из String в Calendar. Более того, если класс действительно содержит сложные методы, лучше попытаться реорганизовать их, используя более объектно-ориентированные методы. Вы всегда можете переключиться с вашего класса «Помощники» на использование различных объектно-ориентированных шаблонов, оставив старые статические методы функционировать как Фасад . Юо будет получать огромные преимущества каждый раз, когда ты сможешь это сделать.

1
ответ дан 1 December 2019 в 21:23
поделиться

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

0
ответ дан 1 December 2019 в 21:23
поделиться