string.IsNullOrEmpty (myString) или string.IsNullOrWhiteSpace (myString) не нарушает правило SRP? - PullRequest
12 голосов
/ 06 марта 2012

Как показывает вопрос,

Поскольку мы используем строковые функции, такие как IsNullOrEmpty или IsNullOrWhiteSpace, как показывает название функций, они выполняют более одной работы, не является ли это нарушением SRP ?

скорее, если это не будет string.isValid (Enum typeofValidation), чем использование шаблона стратегии, чтобы выбрать правильную стратегию для проверки.

или это вполне нормально для нарушения SRP в классе утилит или статических классах.

Ответы [ 4 ]

17 голосов
/ 07 марта 2012

SRP говорит, что функция или класс должны иметь только одну причину для изменения. Что является причиной для изменения? Причиной изменения является пользователь, который запрашивает изменения. Таким образом, класс или функция должны иметь только одного пользователя, который запрашивает изменения.

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

IsNullOrEmpty (String) вряд ли будет обслуживать двух разных пользователей. Пользователь, который заботится о null, скорее всего, тот же пользователь, который заботится о пустом, поэтому isNullOrEmpty не нарушает SRP.

3 голосов
/ 06 марта 2012

В объектно-ориентированном программировании принцип единой ответственности гласит, что каждый объект должен нести единственную ответственность

Вы описываете методы: IsNullOrEmpty или IsNullOrWhiteSpace, которые также самоописываютв том, что они делают, они не являются объектами.string несет единоличную ответственность - отвечать за текстовые строки!

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

2 голосов
/ 06 марта 2012

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

Подумайте о реализации IsNullOrEmpty:

static bool IsNullOrEmpty(string s)
{
    return ReferenceEquals(s, null) || Equals(s, string.Empty);
}

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

Если имена методов вас беспокоят, поскольку они предполагают слишком большую активность для одного метода, оберните их в свои собственные методы с именами, которые подразумевают оценку одного условия. Например:

static bool HasNoVisibleCharacters(string s) { return string.IsNullOrWhitespace(s); }
static bool HasNoCharacters(string s) { return string.IsNullOrEmpty(s); }

В ответ на ваш комментарий:

скажем, я написал функцию наподобие SerilizeAndValidate (ObjectToSerilizeAndValidate), очевидно, этот метод / класс выполняет 2 вещи, Serialize и Validation, что явно является нарушением, некоторые временные методы в классе приводят к кошмару обслуживания, как в приведенном выше примере сериализации и проверки

Да, вы правы, что беспокоитесь об этом, но опять же, вы не можете буквально иметь методы, которые делают только одну вещь. Помните, что разные методы будут работать с разными уровнями абстракции. У вас может быть метод высокого уровня, который вызывает SerializeAndValidate как часть длинной последовательности действий. На этом уровне абстракции было бы очень разумно думать о SerializeAndValidate как об одном действии.

Представьте себе, что вы должны написать набор пошаговых инструкций для опытного пользователя, чтобы открыть диалог свойств файла:

  • Щелкните правой кнопкой мыши файл
  • Выберите «Свойства»

Теперь представьте, что вы пишете те же инструкции для тех, кто никогда раньше не использовал мышь:

  • Наведите указатель мыши на значок файла
  • Нажмите и отпустите правую кнопку мыши
  • Появится меню. Наведите указатель мыши на слово «Свойства»
  • Нажмите и отпустите левую кнопку мыши

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

Методы также позволяют вам соблюдать принцип «не повторяйся» (часто известный как «СУХОЙ»). Если вам нужно как сериализовать, так и проверять объекты во многих частях вашего приложения, вам нужен метод SerializeAndValidate, чтобы уменьшить дублирующийся код. Вам было бы очень полезно реализовать этот метод как простой удобный метод:

void SerializeAndValidate(SomeClass obj)
{
    Serialize(obj);
    Validate(obj);
}

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

0 голосов
/ 06 марта 2012

Я не вижу в этом чего-то большего.Просто убедитесь, что ваша строка проходит необходимое условие.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...