Передача объекта спецификации в хранилище - PullRequest
2 голосов
/ 10 августа 2011

Передача объекта спецификации в хранилище избыточна

Я спрашиваю это, потому что, если мы передадим объект спецификации в методе, подобном FindCustomersCreatedToday,

class CustomerRepository
{
     public List<Customer> FindCustomersCreatedToday(ISpecification ISCreatedToday)
     {
         List<Customer> customers= Load all customers from db;

         List<Customer> newList=new List<>();

         foreach(var customer in customers)
         {  
              if(ISCreatedToday.SatisfiedBy(customer)
              {
                  newList.Add(customer);
              }
         }
     }

}

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

Предположим, если у меня есть 10000 клиентов, и только 10 соответствуют этим критериям.

Разве это не слишком, чтобы передать спецификацию?

Ответы [ 2 ]

2 голосов
/ 11 августа 2011

Как указал Айенде в своем обзоре приложений N-слоя , LINQ - это технология спецификации , которую вы должны использовать, если вам нужен шаблон спецификации. Он имеет преимущество, заключающееся в возможности преобразования в SQL или HQL или любой другой язык запросов, поэтому спецификации, выраженные как Expression<Func<T, bool>>, могут выполняться на источнике данных без необходимости загрузки всех данных.

2 голосов
/ 11 августа 2011

Да, это определенно излишне, если вы ожидаете много клиентов.Вы можете использовать информацию в экземпляре вашей спецификации для генерации соответствующего SQL / HQL или ICreteria (при условии, что вы используете NHibernate).

public IList<Customer> FindCustomers(CreationDateRangeSpecification spec) {
    ICriteria c = _nhibernateSession.CreateCriteria(typeof(Customer));
    c.Add(Restrictions.Between("_creationDate", spec.Start, spec.End));
    return c.List<Customer>();
}

Этот код немного менее выразителен, чем тот, который вы опубликовали, но все же хорош взахват некоторой информации о домене в спецификации.

При работе со спецификацией следует иметь в виду, что это концепция домена.Он относится к домену и должен быть свободен от технологий доступа к данным.Важны технические детали получения данных, они просто не важны на уровне домена, они относятся к уровню доступа к данным.На мой взгляд, такие вещи, как Expression<Func<Customer, bool>>, являются «инфраструктурными» для кода домена.Кроме того, спецификации на основе Linq, как правило, требуют, чтобы доменные объекты представляли свои данные в виде свойств, что иногда нарушает их инкапсуляцию.Таким образом, все это может превратиться в «Linq over Anemic Model ».

Я настоятельно рекомендую вам прочитать DDD book .В нем есть глава, посвященная шаблону спецификации и всем компромиссам, с которыми вы имеете дело.

...