存储库模式和/或/ vs业务逻辑层

我有一个问题,我想知道你的意见。

我正在尝试使用Repository Pattern。 我有一个存储库对象,可以将数据加载到POCO。 我还创建了一个业务逻辑层,它增加了一些function,但基本上包装了POCO。 所以最后我有一个BLL,它使用存储库来加载DAO。

我对这个解决方案不太满意。 我有三层,但我觉得BLL没有提供enoughtfunction来保持它。 另一方面,我不想把我的逻辑放在存储库层或数据访问层?

所以我的问题是我应该在哪里应用逻辑? 您使用哪种解决方案(DAO + repo或DAO + BLL + rep或任何其他解决方案)?

在设计域时,有两种基本的方法可以考虑业务规则。

1.)域实体是基本的POCO / DTO 。 然后你将它们交给域名服务。 这些服务可以像另一个类一样简单,或者它们实际上可以是位于另一个服务器上的实际服务。

var user = repository.Find(x => x.UserName == userName); if (userLogonService.IsValidUser(user, password)) { userLogonService.UpdateUserAsLoggedOn(user); } repository.SaveChanges(); 

2.)域实体包含它们自己的操作逻辑。 这更接近许多MVC模式将遵循的内容。 既然你问过,这就是我喜欢的模特。

 var user = repository.Find(x => x.UserName == userName); if (user.CheckPassword(password)) { user.LogOnNow(); } repository.SaveChanges(); 

两者都是完全有效的模式。 #1有一个离散的业务操作层,但是遇到了贫血域模型 。 如果域开始变得复杂,或者模型可以做很多事情,#2可以导致大域实体。

编辑#1:对John Kraft的回应

Oven.Bake(myPizza)与myPizza.Bake()

我大多同意。 你有一个单独的烤箱服务,或者你有几十个可用的烤箱存储在烤箱存储库中烤箱只是另一个域实体? 在#2中,烤箱是域的一部分。 我倾向于进行域建模的方式, 大多数名词都是域实体 ,除非你100%确定只有一个东西。

但披萨在烘烤时会发生一些事情。

 interface ICanBeBaked { int BakeMinutes { get; } int BakeTemp { get; } void Bake(); } class Pizza : ICanBeBaked { int BakeMinutes { get { return 15; } } int BakeTemp { get { return 425; } } void Bake() { // melt cheese! this.isBaked = true; } } class Oven { void Bake(ICanBeBaked thingToBake) { // set the temp, reserve this oven for the duration, etc. thingToBake.Bake(); } } 

我的“DAL”(更多是本土的ORM,这是另一个话题)本身就是几层; 一个提供存储库和一些活动记录模式支持的抽象,下面是实际的数据访问代码。

此时我们有一个最小的业务层,但真正的原因是它很薄,因为在网页代码隐藏中嵌入了太多(遗留)业务逻辑。 随着重构,我期望业务层增长,增长和增长。

这是相当标准的分层。 你没有说明为什么你对目前的筹码不满意,但请记住,这样做的核心原因是职责分离。 您可能还想了解域驱动设计的概念; 它为围绕业务策略和实践组织代码提供了大量的思考,而不是专门的软件问题。 它是您工具箱中非常有用的分析工具。