BDD / DDD Где разместить спецификации для проверки базовых сущностей? - PullRequest
3 голосов
/ 02 октября 2009

В качестве альтернативы, считается ли валидация базовой сущности спецификацией?

В целом, лучше ли сохранять базовую проверку сущности (имя не может быть пустым или пустым, дата должна быть больше, чем ххх) в фактической сущности или вне ее в спецификации?

Если в спецификации это будет выглядеть? Будете ли вы иметь спецификацию для каждого поля или обернуть все в одну спецификацию типа EntityIsValid?

Ответы [ 2 ]

4 голосов
/ 03 октября 2009

Мне кажется, что как только люди немного узнали о DDD, они выбирают шаблон спецификации и надеются применить его повсюду. Это действительно анти-паттерн Golden Hammer .

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

Помните, что DDD - это итеративный подход, поэтому вам не нужно понимать его «правильно» с первого раза. Я бы начал с размещения базовой проверки внутри сущностей. Это хорошо согласуется с основной идеей OOD, поскольку позволяет объекту, представляющему концепцию, знать допустимые диапазоны данных.

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

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

public class MyEntity
{
    private string name;

    public MyEntity(string name)
    {
        if(string.IsNullOrEmpty(name))
        {
            throw new ArgumentException();
        }
        this.name = name;
    }

    public string Name
    {
        get { return this.name; }
        set
        {
            if(string.IsNullOrEmpty(value))
            {
                throw new ArgumentException();
            }
            this.name = value;
        }
    }
}

Правило, согласно которому имя не может быть пустым, теперь является инвариантом для класса: теперь класс MyEntity не может попасть в состояние, когда это правило нарушено.

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

1 голос
/ 12 октября 2009

У сущностей есть и данные, и поведение, поэтому позволить вашим сущностям гарантировать, что их инварианты - это путь ИМХО. Иначе, вы можете получить модель анемического домена [Фаулер].

Если ваш контекст позволяет вам применять правила в установщиках, как предполагает Марк Симанн, было бы замечательно, поскольку в вашей модели нет всей логики «IsValid» и / или «BrokenRules».

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

  1. Классическое веб-решение для ответа / запроса, в котором веб-страница отображает все нарушенные правила объекта при сбое сохранения.

  2. Модель считывается из базы данных, которая обновляется извне (следовательно, сущность не может быть недействительной, несмотря на логику установщика, если только вы не позволите своему ORM использовать установщики, но для нас все было узнать о действительности).

...