需求如下:需要从数据库的Cargo表中取出商品名称为“钉子”的货物。
可以这样做:
public class CargoRepository
{
public List SelectByPartName(string partName){}
}
当需求发生变化了,它要从数据库的Cargo表中取出商品编码为“0001”的货物。
可以这样做:
public class CargoRepository
{
public List SelectByPartCode(string partCode){}
}
当需求又一次变化了,它要从数据库的Cargo表中取出商品名称为“钉子”并且商品编码为“0001”的货物。
这时候问题严重了,看下上面的方法都是一些特定的查询,可能还有很多这样的查询。
他们单个的查询通过组合又形成了新的查询。这就是组合爆炸。
有两种模式可以解决这样的问题:Specification-[Evans的DDD]和Query Object[Fowler,PEAA]
这里只讨论Specification
在对DDD一书中提到:
(原文如下:业务规则不适于放在任何已个实体或值对象中,而且规则的变化和组合会掩盖那些领域对象的基本含义。)
有时经常造成组合爆炸。规格是模型的一部分,将它们从实体或值对象中独立出来有助于使模型更加清晰,它表达的是业务的规则。规格是值对象,它用来判断对象是否满足标准的谓词。谓词是指计算结果未true或false的函数,可以用and、or、not操作符连接。
对规格的接口定义:
然而我们却不常这样做。因为有些ORM框架采用对象的属性来查询。在基础结构层中生成SQL,这样我们就不需要这样麻烦了。