存储库/模型中的商业逻辑好吗?

时间:2012-02-20 23:28:29

标签: design-patterns model domain-driven-design

如果你有一个业务规则,用户(或用户界面)永远不会看到表中的前30个项,你应该把这个过滤器放在Repository的GetAll()中吗?这意味着,存储库是否会处理数据过滤,将数据模型化为像ViewModel或Controller一样交给调用者?我听说模型应该很厚,控制器/ vms应该很轻。

我遇到的问题是另一个与我共享项目的开发人员,他的所有存储库(每个表一个)都使用相同的实现,只是将LinqToSql类型的属性复制到域类型。除了通过提供的Func更新和删除或获取数据之外,存储库本身没有逻辑。

另一方面,我为每个表创建了一个存储库(继承自T的IRepository),并将特定逻辑放在一些(不是全部)我认为需要逻辑来交还域对象的地方。

所以在我的情况下,业务逻辑可以在存储库中完成,在他的情况下,它必须由用户完成,可以是服务或直接ViewModel。哪个更优选?

1 个答案:

答案 0 :(得分:6)

  

如果你有一个业务规则,用户(或用户界面)永远不会看到表中的前30个项目,你应该把这个过滤器放在Repository的GetAll()中吗?

首先,这听起来不像是商业规则。业务规则以ubiquitous language表示,除非您正在使用数据库引擎,否则此语言不包含“table”之类的字。

回答你的主要问题,过滤逻辑绝对可以存在于存储库中。这就是repository的用途:封装存储,检索和搜索。关于存储库最重要的一点是它的接口属于域层,但其实现属于数据访问层。所以在你的情况下代码看起来像这样:

域:

// repository interface:
public interface Orders{ 
   IList<Order> GetDelinquent();
}

数据访问:

public SqlOrders : Orders{ 
   IList<Order> GetDelinquent(){
      // do whatever needs to be done to find
      // delinquent orders in sql database.
      // filter first 30 records for example
   }
}

请注意,存储库界面会将域置于焦点(我们不会说'除了前30条记录以外的所有',我们说'拖欠')。

  

我遇到的问题是另一个与我共享项目的开发人员,他的所有存储库(每个表一个)都使用相同的实现,只是将LinqToSql类型的属性复制到域类型。除了通过提供的Func更新和删除或获取数据之外,存储库本身没有逻辑。

     另一方面,我为每个表创建了一个存储库(继承自T的IRepository),并将特定逻辑放在一些(不是全部)我认为需要逻辑来交还域对象的地方。

通用存储库界面通常是一个坏主意,它太以数据为中心,太过于CRUDy,请参阅this answer了解详细信息和链接。

  

所以在我的情况下,业务逻辑可以在存储库中完成,在他的情况下,它必须由用户完成,可以是服务或直接ViewModel。哪个更优选?

业务逻辑和数据访问逻辑之间存在很大差异。您希望避免将业务逻辑放入存储库实现中。此逻辑属于域对象。