Изменен шаблон спецификации (Кандидат в конструктор)

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

Например, шаблон спецификации выглядит следующим образом:

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

Но для меня это не очень читабельно:

 _customerAccountIsActive
.And(_hasReachedRentalThreshold)
.And(_customerAccountHasLateFees)
.IsSatisfiedBy(this); 

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

public abstract class Specification<TEntity> : ISpecification<TEntity>
{
    protected TEntity _candidate;

    public Specification(TEntity candidate)
    {
        _candidate = candidate;
    }

    public bool IsSatisfied()
    {
        return IsSatisfiedBy(_candidate);
    }
}

И я даже перегружен оператором bool, так что я могу написать что-то вроде этого:

_customerAccountIsActive 
&& _customerAccountHasLateFees
&& _hasReachedRentalThreshold

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

1 ответ

Подобный вопрос вы можете найти здесь. Как адаптировать шаблон спецификации для оценки комбинации объектов?, У меня та же проблема с тобой, и я думаю, что есть две адаптации.

Моя проблема сравнивает 2 объекта 2 разных типов TEntity в одной спецификации.

Прямо сейчас я пытаюсь добавить второй объект в IsSatisfied (кандидат T) следующим образом: IsSatisfied(T firstCandidate, K secondCandidate)

Таким образом, спецификация будет приходить спецификация, но я думаю, что я потеряю способность сочетать спецификацию со спецификацией.

До сих пор у меня не было хорошей идеи о добавлении второго кандидата в спецификацию.

Есть 2 обходных пути, которые я могу думать:

  1. Использование объекта параметра и использование этого объекта в качестве объекта-кандидата:

    public class ParameterObject<T,K>
    {
      public T FirstObject { get; set; }
      public K SecondObject { get; set; {
    }
    
    
    public SomeSpecification: Specification<ParameterObject<Order, Customer>>
    
    public bool IsSatisfied(ParameterObject candidate)
    {
       // do some check between order and customer candidates.
    }
    
  2. Использование инжекторного инжектора:

    public class OutOfRangeOrderSpeficiation: Specification<Order>
    {
       private ICriteria _criteria;
    
        public OutOfRangeOrderSpeficiation(ICriteria criteria)
        {
           _criteria = criteria;
        }
    
        public bool IsSatisfied(Order candidate)
        {
          // comparing between order candidate and _criteria.
          return false;
        }
    }
    
Другие вопросы по тегам