传递规范对象在Repository中是否过度

时间:2011-08-10 19:53:00

标签: domain-driven-design

传递规范对象在存储库中是否过度

我问这个是因为,如果我们在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 个答案:

答案 0 :(得分:2)

是的,如果你期待很多顾客,这肯定是一种矫枉过正。您可以使用规范实例中的信息生成适当的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。它有一章专门讨论规范模式以及您正在处理的所有权衡。

答案 1 :(得分:2)

正如Ayende指出他的N-layer app review LINQ是规范技术,如果你需要规范模式,你应该使用它。它具有可转换为SQL或HQL或任何其他查询语言的优点,因此可以在数据源上执行表达为Expression<Func<T, bool>>的规范,而无需下载所有数据。