2012-05-29 42 views
3

我有以下基本实体:收集过滤逻辑应该放在域驱动的应用程序中去哪里?

public class Basket 
{ 
    public List<Product> Products {get;set;} 
} 

public class Product 
{ 
    public string Name {get;set;} 
    public decimal Price {get;set;} 
} 

而且我想在一篮子低于固定价格的所有产品的列表。如果这个逻辑走在Basket,像这样:

public class Basket 
{ 
    public List<Product> Products {get;set;} 
    public List<Product> CheapProducts 
    { 
     get { return Products.Where(p => p.Price < 5).ToList(); } 
    } 
} 

还是应该在一个服务类,ProductFilterer去,要和产品的整个列表作为参数,将返回的产品的过滤列表。或者,也许它应该直接进入调用类的方法?

还是别的什么?最佳做法是什么?

回答

2

如果“廉价产品”的概念是一流的领域概念,并且必须在无所不在的语言中引入,我会做的就是与领域专家一起看。

如果是这种情况,史蒂夫的规范解决方案以优雅的方式解决您的问题。

如果廉价性不重要或者不那么明确(例如,如果便宜阈值在整个应用程序中有所不同),我不打算为它创建特定的实体,只是在相应的条件下过滤Basket.Products时在调用代码时需要。

+0

+1。 :) –

0

是的,我建议保持你的DTO与商业逻辑分开。我喜欢将数据对象视为与数据访问,业务和UI层完全分离的层。如果你有一个更一般的ProductBusiness类,我会建议把它放在那里,除非它有一个单独的filterer类是非常有用的。

0

您的购物篮类不应该知道如何直接过滤,它有一个暴露的函数,允许它从您的建议返回ProductFilter的结果是正确的。代码的外观应该是这样的:

class ProductFilter 
{ 
    filterCheapProducts(Collection<Product> productsToFilter) 
    { 
     return Products.Where(p => p.Price < 5).ToList(); //I assume your code is correct 
    }  
} 

class Basket 
{ 
    Collection<Product> getCheapProducts() 
    { 
      return filter.filterCheapProducts(this.products); 
    } 
} 
2

您可以考虑查看Specification Pattern。该链接有一个很好的示例实现,但简而言之,该模式允许您基于简单的谓词(或规范)创建复杂的选择标准。

快速(或不完全)实现使用委托这样的图案可以做这样:

public class Specification<T> 
{ 
    Func<T, bool> _spec; 
    public Specification(Func<T, bool> spec) 
    { 
     _spec = spec; 
    } 

    public bool IsSatisifedBy(T item) 
    { 
     return _spec(T); 
    } 
} 

// ... 

_cheapProductsSpecification = new Specification<Product>(p => p.Price < 5); 
var cheapProducts = Basket.Products.Where(p => _cheapProductsSpecification.IsSatifisifedBy(p)); 

这是当然的,简单的和可能冗余的例子,但如果添加的同时,或者和Not(请参阅链接),您可以将复杂的业务逻辑构建到规范变量中。

+1

只需添加一个点,Evans就建议将隐藏在方法中的业务规则隐藏到对象中。看一看[Cargo' e'Voyage']的示例(http://ptgmedia.pearsoncmg.com/images/chap1_0321125215/elementLinks/01fig10.gif)。使用规范模式,您可以重复使用这些规则并提高内聚性:就您而言,您可以将这些规则应用于存储库中,以供示例使用。 – lcardosobr

相关问题