Вы правы, что если вы уверены, что никогда не возвращаете нули, просто пропустите нулевую проверку перед вызовом метода в первой реализации. Аналогично, если вам нужно сделать что-то особенное в том случае, если UseA()
нужно что-то сделать по-другому на нулевом объекте, вам все равно нужно явно проверить нулевой объект. Тем не менее, какой нулевой шаблон объекта действительно помогает - это ситуации, в которых это не имеет большого значения.
Возьмите, к примеру, большинство образцов наблюдателя. Если вы реализуете свой шаблон наблюдателя как члена своего класса, для которого может быть только один наблюдатель, и хотите сообщить наблюдателю, что ваш класс что-то сделал, для класса не имеет значения, является ли наблюдатель нулевым или нет.
Это также иллюстрируется пустыми классами контейнеров, которые по существу представляют собой шаблон нулевого объекта: вместо возврата нулевого контейнера из запроса вы просто возвращаете пустой контейнер. Для таких вещей, как итерация через все записи контейнера, часто не имеет значения, пуст он или нет, поэтому избавление от необходимости нулевой проверки делает код более удобным для обслуживания/более читаемым. Однако, если вы хотите заполнить представление своего набора данных, вам все равно нужно явно показывать разные «Нет записей». который проверяет пустой контейнер.
Редактировать для ясности
одна проблема смотрит только на него с сайта вызова. Как и большинство шаблонов проектирования, это должно охватывать обе стороны, которые должны быть полностью использованы. Рассмотрим:
public PossiblyNull GetSomethingNull()
{
if (someBadSituation())
return null;
else
return SomehowProduceSomething();
}
против
public PossiblyEmpty GetSomethingEmpty()
{
if (someBadSituation())
return StaticEmptySomething();
else
return ProdueSomethingYay();
}
Теперь, ваш код вызова, вместо того, чтобы смотреть как
public void DoSomethingWithChild(Foo foo)
{
if (foo != null)
{
PossiblyNull bar = foo.GetSomething();
if (bar != null)
bar.DoSomething();
}
}
может быть
public void DoSomethingWithChild(Foo foo)
{
if (foo != null)
foo.GetSomething().DoSomething();
}
Я согласен с вашими комментариями и Карлом внизу. Он считает, что это чересчур параноидально, усложняет код, замедляет просмотры кода и т. Д. Проблема заключается в защите аргумента «что-если»: «Что, если« что-то »происходит в производстве, и мы сбой, потому что мы не проверяли значение null ? Как бы вы отреагировали на это? – TERACytE
@TERACyTE: Ну, добавление ветвей кода для нулевых состояний, когда они не нужны, также добавляет сложности, которые сложнее поддерживать. Идея не-check-for-null довольно раздельна из шаблона нулевого объекта, который предполагает использование null в качестве регулярного расширения, и рассматривает его скорее как исключительный случай. – Tanzelax
(редактируется сообщение с примером). Идея здесь состоит в том, что если все еще может быть нулевым, вы все же необходимо проверить наличие нулей. Однако, беря возможные ** источники ** этих нулей, вы делаете ветви кода более удобными. – Tanzelax