Если класс Utilities является злом, куда я могу поместить свой общий код?

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

Это очень простое правило, и я считаю, что до сих пор у меня никогда не было проблем с этим правилом.

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

Где мне разместить эту функцию (+1 перегрузка)?

Если я отношу его к классу «Утилиты», я чувствую себя грязным. Если я прикреплю его к полусвязанному классу и позволю другим классам вызывать его напрямую, я буду чувствовать себя хуже.

Этот конкретный фрагмент кода в основном нарезает IList<PointF> в нормализованный список. Я чувствую прямо сейчас, что добавление его в качестве метода расширения на IList<PointF> может быть лучшим выбором...


person John Gietzen    schedule 27.07.2010    source источник
comment
Я согласен, глобальные переменные - это зло. У них, кажется, есть собственные умы, посвященные подрыву вашего кода.   -  person Rafe Kettler    schedule 27.07.2010
comment
Глобальное состояние проблематично, но глобальные функции — это просто логика, которую можно использовать повторно, и у которой слишком мало входов/выходов, чтобы их стоило инкапсулировать в классе. Я не вижу никаких проблем с методами Helper или Utility, сгруппированными в статические классы Helper или Utility с соответствующими именами.   -  person Dan Bryant    schedule 27.07.2010
comment
Я предпочитаю использовать метод подтягивания вместо класса Utility/Helper — метод подтягивания   -  person Sumeet Patil    schedule 10.12.2017


Ответы (3)


Если это операция над IList<PointF>, то это должен быть метод расширения для IList<PointF>.

Как правило, следует избегать классов типов Utils и Helper. Чаще всего вы обнаружите, что то, что вы можете считать служебным методом, на самом деле является довольно специфическим методом, который, вероятно, принадлежит к отдельному классу (как вы и говорите). Однако будут случаи, специфичные для предметной области, когда Util-подобные классы (классы, которые группируют связанные полезные методы) являются допустимыми объектами.

person Håvard S    schedule 27.07.2010
comment
+1 Методы расширения идеально подходят для такого рода проблем - person Diadistis; 27.07.2010
comment
Да, но я оговорюсь, что если это расширение, то оно должно иметь бегло звучащее имя... что-то вроде points.NormalizeIntoSegments(50) вместо предпочитаемого мной Utilities.Segment(points, 50). - person John Gietzen; 27.07.2010
comment
как насчет класса NormalizedIList, расширяющего IList? - person atk; 27.07.2010
comment
Я могу ошибаться, но если Utilities.Segment(points, 50) в порядке, то что не так с points.Segment(50)? - person Håvard S; 27.07.2010
comment
@Diadistis Что такое метод расширения? - person Koray Tugay; 18.12.2015
comment
@KorayTugay Методы расширения позволяют добавлять методы к существующим типам, не создавая новый производный тип, перекомпиляция или иное изменение исходного типа. - person Diadistis; 18.12.2015
comment
Методы расширения и статические служебные методы на самом деле одно и то же. Единственная разница заключается в синтаксисе вызова метода, где первый аргумент метода расширения помещается перед оператором .. То, как вы используете методы расширения и статические служебные методы для разработки программного обеспечения, совершенно одинаково. Меня сбивает с толку тот факт, что этот ответ, кажется, подразумевает, что есть разница. - person Lii; 27.07.2017
comment
Я из мира Java. У меня есть правило. Если я хочу добавить функциональные возможности в класс API, например Date, String, я создаю определенный класс Util. как DateUtil, StringUtil. В противном случае, как вы сказали, большая часть метода util позже обнаруживается, что он принадлежит классу. - person seal; 10.11.2019

Нет ничего плохого в «глобальных» переменных и методах. Вы используете их все время. Фреймворк любит называть их «статическими» классами или «статическими» методами.

Мне это редко нужно, но обычно я добавляю внутренний статический класс Util в пространство имен, что метод/переменная нужна для C# и модуль для VB.NET.

Примеры из .NET Framework

  • System.Collections.Specialized.CollectionsUtil
  • System.Net.WebUtility
  • Проверьте исходный код Microsoft для .NET Framework. Вы найдете множество внутренних служебных классов.
person AMissico    schedule 27.07.2010
comment
Обратите внимание, что все примеры из BCL сгруппированы вокруг определенной ответственности. Нигде нет общего класса Utils. - person Ben Voigt; 27.07.2010
comment
Что такое БКЛ? Вы имеете в виду библиотеки базовых классов (BCL)? - person AMissico; 27.07.2010
comment
Откройте .NET Reflector. Найдите утилиту. Существует 256 примеров, использующих сборки по умолчанию (BCL) 4.0, загруженные .NET Reflector. - person AMissico; 27.07.2010

Конечно, вы должны поместить его в класс ListUtilities или PointListUtilities. Тогда вы не нарушаете принцип единой ответственности, который является основной проблемой универсального класса «Утилиты».

person Ben Voigt    schedule 27.07.2010