Допускается более одного значения "без значения" в пространстве значений
Я использую строковый тип для своего атрибута Id на всех объектах моего домена. Например:
public class Person {
property string Id { get; set; }
// ... more properties
}
Здесь нет трюков. null
представляет значение "без значения", когда создается новый объект Person и до его сохранения, Id
останется null
,
Сейчас идет дискуссия, чтобы увеличить пространство "без стоимости" и сказать, что null
Пустая строка и строки пробела являются значениями "без значений".
Т.е. проверить, является ли сущность новой, а не делать: if (person.Id == null)
это станет if (string.IsNullOrWhiteSpace(person.Id))
По моему скромному мнению, это запах или нарушение принципа дизайна, но я не могу понять, какой именно.
Вопрос: какой (если таковой имеется) принцип проектирования нарушает это решение (решение разрешить больше, чем просто null
представлять значение без стоимости)?
(Я думаю, это должно быть что-то похожее на принцип бритвы Оккама, или энтропию, или KISS, я просто не уверен)
2 ответа
Это нарушает принцип KISS. Если нет особой необходимости обрабатывать пустые строки рядом с нулями, то зачем это делать? Все операции теперь должны проверять два значения вместо одного. При исследовании БД простой SELECT для поиска записей "NULL" становится немного менее тривиальным без веской причины.
Другим нарушенным принципом является принцип наименьшего удивления - обычно люди ожидают, что только значения NULL будут представлять объекты NULL. Дизайн с двумя особыми значениями менее очевиден и менее "читабелен".
Если за этими "вторыми категориями-специальными объектами" должно быть скрыто что-то еще, то это следует сделать явным. В противном случае должно быть тривиально обрабатывать ввод пустой строки и сохранять его как NULL, чтобы быть согласованным с остальной частью системы.
РЕДАКТИРОВАТЬ:
Я также нашел другой "принцип" в книге Боба Мартина " Чистый код" - "одно слово на концепцию", который как-то связан с этим случаем. Пустая строка и NULL - это два "слова", используемые для одного понятия, поэтому они явно нарушают это правило.
Я собираюсь выйти на конечности и сказать, определяя оба null
а также ""
так как пустая строка для вашего приложения не нарушает никаких принципов проектирования и не является запахом кода. Вам нужно просто четко определить семантику поля для вашей цели, и вы сделали это (т.е. в вашем приложении, но null
а также ""
значит "нет значения").
У вас должны быть тесты, обеспечивающие правильное поведение обоих null
а также ""
,
Это не означает, что вы также не можете принять решение, чтобы все пустые строки были равны нулю. Это одинаково правильное решение. Вам понадобятся тесты, которые подтверждают, что во всех случаях, когда вы устанавливаете "Нет значения", фактическое значение равно нулю. Возможно, вы захотите пойти по этому пути, если ваш уровень персистентности ожидает нулевое значение, и только нулевое значение указывает на отсутствие значения.
Таким образом, в этом случае нет неправильных решений, только решения.