При создании Вместилища Класс AppToolbox - действительно ли это - Плохая Практика?

Вторым примером был бы тот для движения с, не только для удобочитаемости, но и из-за того, что в первом примере, Если НЕ value1 возвратит булево значение, которое будет сравнено с value2. IOW, необходимо переписать тот пример как

If NOT (value1 = value2)

, который просто делает использование НЕ ключевого слова бессмысленным.

6
задан Bob Kaufman 31 October 2009 в 02:55
поделиться

8 ответов

Great question. I always find that any sufficiently complex project require "utility" classes. I think this is simply because the nature of object-oriented programming forces us to place things in a neatly structured hierarchical taxonomy, when this isn't always feasible or appropriate (e.g. try creating an object model for mammals, and then squeeze the platypus in). This is the problem which motivates work into aspect oriented programming (c.f. cross cutting concern). Often what goes into a utility class are things that are cross-cutting concerns.

One alternative to using toolbox or utility classes, are to use extension methods to provide additional needed functionality to primitive types. However, the jury is still out on whether or not that constitutes good software design.

My final word on the subject is: go with it if you need, just make sure that you aren't short-cutting better designs. Of course, you can always refactor later on if you need to.

6
ответ дан 8 December 2019 в 18:37
поделиться

Я думаю, что статический вспомогательный класс - это первое, что приходит на ум. Это настолько распространено, что некоторые даже называют это частью объектно-ориентированного дизайна. Однако самая большая проблема со вспомогательными классами заключается в том, что они имеют тенденцию превращаться в большую свалку. Думаю, я видел, как это происходило в нескольких более крупных проектах, в которых я участвовал. Вы работаете над классом и не знаете, куда вставить ту или иную функцию, поэтому вы помещаете ее в свой вспомогательный класс. В этот момент ваши помощники плохо понимают, что они делают. Само имя helper или util в названии класса ничего не значит. Я думаю, что почти все гуру объектно-ориентированного программирования выступают против помощников, поскольку вы можете очень легко заменить их более описательными классами, если вы уделите этому достаточно внимания. Я склонен согласиться с этим подходом, поскольку считаю, что помощники нарушают принцип единой ответственности. Честно говоря, отнеситесь к этому с недоверием. Я немного самоуверен в ООП :)

2
ответ дан 8 December 2019 в 18:37
поделиться

There is nothing wrong with this. One thing is try to break it up into logical parts. By doing this you can keep your intellisense clean.

MyCore.Extensions.Formatting.People
MyCore.Extensions.Formatting.Xml
MyCore.Extensions.Formatting.Html
1
ответ дан 8 December 2019 в 18:37
поделиться

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

1
ответ дан 8 December 2019 в 18:37
поделиться

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

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

При этом, я лично не

0
ответ дан 8 December 2019 в 18:37
поделиться

Я опубликовал комментарий, но подумал, что могу уточнить немного подробнее.

Что я делаю, так это создаю общую библиотеку с пространствами имен: [Организация ]. [Product] .Common в качестве помощников корневого и подпространства имен.

Несколько человек здесь упоминают такие вещи, как создание класса и добавление некоторых вещей, которые они не знают, куда еще поместить. Неправильно. Я бы сказал, что даже если вам нужен один вспомогательный метод, он с чем-то связан, поэтому создайте статический вспомогательный класс с правильным именем (IoHelper, StringHelper и т. Д.) И поместите его в пространство имен Helpers. Таким образом, вы получаете некоторую структуру и своего рода разделение задач.

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

0
ответ дан 8 December 2019 в 18:37
поделиться

В этих примерах я был бы более склонен расширить String:

class PhoneNumber extends String
{
     public override string ToString()
     {
         // return (999) 999-9999
     }
}

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

РЕДАКТИРОВАТЬ:

Как указано ниже, вы не можете переопределить String в C #. Я пытался сказать, что эта операция выполняется с телефонным номером, поэтому функция принадлежит именно ему:

interface PhoneNumber
{
    string Formatted();
}

Если у вас разные форматы, вы можете обмениваться реализациями PhoneNumber, не засоряя свой код операторами if, например,

Вместо:

if(country == Countries.UK) output = Toolbox.PhoneNumberUK(phoneNumber);
else ph = Toolbox.PhoneNumberUS(phoneNumber);

Вы можете просто использовать:

output = phoneNumber.Formatted();
2
ответ дан 8 December 2019 в 18:37
поделиться

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

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

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

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

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

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

1
ответ дан 8 December 2019 в 18:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: