Изменен шаблон спецификации (Кандидат в конструктор)
Я знаю, что шаблоны проектирования устанавливаются дизайном, а не конкретным кодом, но иногда меня беспокоит, что я слишком сильно согнул шаблон и больше не следую дизайну.
Например, шаблон спецификации выглядит следующим образом:
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 обходных пути, которые я могу думать:
Использование объекта параметра и использование этого объекта в качестве объекта-кандидата:
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. }
Использование инжекторного инжектора:
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; } }