2009-11-10 2 views
4

Почему Fowler PoEAA с. 498 определяет шаблон нуля-объект следующим образом (образец укороченного, язык C#, но не имеет значения):Fowler Null Object Pattern: Зачем использовать наследование?

public class Customer 
{ 
    public virtual string Name {get; set;} 
} 

public class NullCustomer : Customer, INull 
{ 
    public override Name 
    { 
    get { return "ImTheNull";} 
    // setter ommitted 
    } 
} 

INull используются в качестве интерфейса маркеров. мне не очень нравится этот подход по трем причинам:

  1. свойству должно быть отмечено виртуальными
  2. Я не могу запечатать мои классы сущностей больше
  3. По крайней мере (п + 1) новые типы введено (п нулевые объекты, один интерфейс маркера)

Почему не реализуется так:

public class Customer 
{ 
    public static readonly Customer NullCustomer = new Customer(){Name = "ImtTheNullCustomer";} 

    public string Name {get; set;} 
} 

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

+0

Не делайте метод виртуальным или оставьте класс незапечатанным по этой причине. Хотя у меня огромное уважение к Мартину Фаулеру, во многих его примерах, связанных с наследованием, существует определенная явная предвзятость. По умолчанию Java-методы являются виртуальными. В C# их нет, и это дизайнерское решение было принято специально из-за воспринимаемых проблем с виртуальным по умолчанию.Во всяком случае, используйте этот шаблон, если NullCustomer будет действительным клиентом. Хорошей метрикой является сравнение ее с пустым списком. Пустой список - отличный список, и его распространение не наносит вреда. Это может быть не так. –

ответ

10

Причиной наследования является переопределение поведения класса. То, как вы думаете об этом, похоже на то, что вы собираетесь проверить, имеет ли объект, который у вас есть, статический экземпляр NullCustomer, чтобы принять решение, однако точка нулевого объекта должна поддерживать Liskov's substitution principle.

Другими словами, вы используете нулевой объект для задания ссылки, и у вас не будет специальной проверки для него, вы просто будете использовать его, и у него должно быть другое поведение (на самом деле это отсутствие поведения).

+0

Вы сделали опечатку в имени Лискова. –

+0

ОК, так что проблема в методах (вычисления и т. Д.), А не просто получить свойства набора? (тот же вопрос для Алистера) –

+1

Да, поведение в методах и даже свойствах. Обратите внимание, что в вашем примере у сеттера отсутствует нулевой объект. Это изменяет поведение базового класса, в котором нулевой объект доступен только для чтения. – Chap

1

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

С классом Null класс возвращает то, что имеет наибольший смысл, если такие проверки не требуются.

Например, класс клиента может вернуть общий трат доллара этим пользователем после опроса БД по мере необходимости. NullCustomer мог бы только return 0;. С магическим значением он либо извлечет информацию для фиктивного пользователя из БД, либо должен выполнить другую конкретную проверку, прежде чем делать разумную вещь.

+0

ОК, поэтому проблема заключается в методах (вычислениях и т. Д.), А не просто получить свойства набора. –

+0

Действительно ли 0 по умолчанию? Это зависит от того, что вы пытаетесь сделать. Вы не хотите вставлять NullCustomer в свою базу данных ... –

0

Добавление к тому, что сказал Чап. Шаблон Null Object используется так, чтобы был допустимым набор значений по умолчанию. Кроме того, если вы попытаетесь использовать NullCustomer в MVC, вы все равно сможете получить доступ к объекту, представляющему модель, вместо того, чтобы учитывать потенциальные несуществующие данные. [Проверка нулям]

0

Я не C# программист, но это выглядит, как в вашем втором примере, что вы могли бы сделать эквивалент:

Customer.NullCustomer.Name = "Not Null"; 

В общем, объекты имеют поведение, а не только данные , поэтому он становится более сложным.

+0

Да, вы получили это право, другие уже упоминали об этом. Спасибо за комментирование в любом случае. –

Смежные вопросы