Подтвердить что ты не робот

DDD Использование шаблона спецификации для проверки

Я думаю использовать шаблон спецификации для целей проверки. Трудно сказать, как указать пользователю, почему некоторая спецификация не была удовлетворена. Что делать, если Specification.IsSatisfiedBy() не только вернет значение bool, но и причину сбоя. Он будет выглядеть примерно так:

interface ISpecification<T>
{
  CheckResult IsSatisfiedBy(T candidate);
}

где CheckResult:

class CheckResult
{
  public bool IsSatisfied { get; }
  public string FailureReason { get; }
}

В Fowler and Evans существует концепция частично удовлетворительной спецификации, целью которой является дать объяснение, что именно не было выполнено. Однако в этом документе он реализован как дополнительный метод restundUnsatisfiedBy, который возвращает спецификацию, которая не была выполнена Кандидатом.

Итак, вопрос: при использовании Спецификации для целей валидации, как обеспечить обратную связь с пользователем о том, что данная Спецификация не была удовлетворена? Является ли решение, которое я представил выше, хорошо?

4b9b3361

Ответ 1

Хотя вы можете использовать классы спецификаций для проверки, я бы предложил вам сохранить их как отдельные концепции в вашем домене. Вы можете обнаружить, что вам нужно повторно использовать одни и те же базовые спецификации, но вам нужно вернуть разные "причины отказа" в зависимости от цели и контекста. Подробнее см. в этой статье.

Автор сообщения, упомянутого выше, также любезно передал код github и разместил код как NCommon. Просмотрите эти области, в частности:

Технические характеристики: https://github.com/riteshrao/ncommon/tree/v1.2/NCommon/src/Specifications

Валидации: https://github.com/riteshrao/ncommon/tree/v1.2/NCommon/src/Rules (особенно классы для ValidationResult и ValidationError)

Ответ 2

У меня была та же проблема. Я создаю декоратор проверки для спецификации (код JAVA).

  interface Validator<T>{
    Respond validate(T t)
  }


  class abstract ValidationSpecificationDecorator<T> implements Validator<T> {
  Specification<T> spec;

  ValidationSpecificationDecorator(Specification<T> spec){
    this.spec =  spec;
  }

  public Respond  validate(T t) {
    Respond respond = new Respond();
    if(!spec.IsSatisfiedBy(t){
       respond.add(error(t));
    }
    return respond;
  )

  public abstract Error error(T t);

  }