打破业务逻辑和数据层似乎重叠的最佳设计? [关闭]

Posted

技术标签:

【中文标题】打破业务逻辑和数据层似乎重叠的最佳设计? [关闭]【英文标题】:Best designs for breaking down business logic and data layer when they seem to overlap? [closed] 【发布时间】:2010-10-04 00:34:39 【问题描述】:

我正在构建一个 MVC Web 应用程序(使用 Spring MVC 框架),但我对设计特定区域的最佳方式感到有些困惑。

应用程序必须与一系列 Web 服务进行交互,这些 Web 服务的设计并没有那么大,并且它们本身并没有提供太多抽象 - 基本上每个创建/更新/检索/都有一个 Web 服务方法每个“数据类型”的删除操作,除此之外没有太多的 API。 Web 服务客户端需要知道要调用哪些方法以及以何种顺序来创建它需要的数据 - 换句话说,没有基于“事务”的方法。

例如,简单地创建一个新用户帐户需要调用总共七种不同的 Web 服务方法来设置必要表中的所有记录(user 记录,将正确的 privileges 添加到该用户, 设置用户的billing 详细信息等)。

我正在努力寻找将其抽象化并将其封装在我们的应用程序中的最佳方法。大多数应用程序都遵循标准流程:

request ---> Controller <---> Service/Business-level object <---> DAOs for data access

在我的应用程序中,我使用我自己的一组“域对象”来表示和抽象 Web 服务 WSDL 中定义的数据类型,这样我的域逻辑不依赖于 Web 服务类型,因此我们可以抽象并隐藏我们喜欢的任何细节。

我正在寻找一些意见是设计我上面作为示例提到的“用户创建过程”的最佳方式。正如我所提到的,创建“普通用户”的过程涉及调用七种不同的 Web 服务,但这只是用户的一种“类型”——我们必须能够创建几种不同类型的用户,每个用户都需要不同的要调用的 Web 服务。

目前我只设计了这个“普通用户”创建,作为一个概念证明——我有一个域对象User,一个UserDao 接口,它有getUser(name)createUser(User) 的方法,以及一个WebServiceUserDao,它实现了UserDao 方法并知道如何调用上述七个Web 服务方法。 createUser() 方法由 UserCreationService 调用,这是我的业务/服务级类,而该类又由 SignupController 调用。

但是为了扩展这个逻辑以便能够创建不同的用户类型(在User.getType() 中由不同的值表示,我不确定业务/服务层类和 DAO 之间的界线在哪里. 例如,我应该:

    为每个“用户类型”创建一个UserDao 实现,所以创建每个“用户类型”的逻辑可以封装在它自己的类中,让UserCreationService 决定使用哪个UserDao?这将对应于 1 个服务类:许多 DAO。 我是否应该将UserDao 分成更小的部分,一个对应于需要在 Web 服务/数据库中创建的每个“记录”,即使我的整个应用程序不需要了解这些单独类型中的每一个?然后对各种不同的“用户类型”有不同的UserCreationService 实现?换句话说,即使我不需要相应的PrivilegeBillingPlan 域对象,该策略也会有PrivilegesDaoBillingPlanDao 等。这将是许多服务类:许多 DAO。 在单个WebServiceUserDao 中包含需要为每个“用户类型”调用 Web 服务的所有逻辑?这将有一个非常复杂的缺点 类(并且 PMD 已经在抱怨圈复杂性),但所有这些逻辑都将封装在一个类中,从整体 API 的角度来看,可能会减少复杂性。

我对这个应用程序的一个目标是确保如果我们必须更改数据持久性的细节,我们需要做的就是更改 DAO 实现 - 如果我们必须开始与不同的接口计费系统,我不希望应用程序的任何部分在 DAO 级别之外进行更改。

有什么意见吗?当“业务逻辑”和“数据访问逻辑”似乎重叠时,您会使用哪种策略来决定在哪里分解它们?

【问题讨论】:

【参考方案1】:

当“业务逻辑”和“数据访问逻辑”似乎重叠时,您会使用哪种策略来决定在哪里分解它们?

也许你可以有三层而不是两层:“一个额外的间接级别”。

在顶层,您可能有不了解数据访问的业务逻辑:此业务层使用 UserAccount 等类,可能还有一些工厂方法,如 User.getAccountsAccount.getOwners.

底层可能是一个数据访问层,它是您的包装器或外观,无论您的数据层是什么。

在这两层之间,一层知道您的业务对象是什么(例如用户和帐户),但不知道您的业务逻辑是什么。中间层知道你的数据访问层。中间层的工作是使用数据访问层的 API 来 I/O 业务对象。

【讨论】:

【参考方案2】:

“我不确定在业务/服务层类和 DAO 之间的界限在哪里。”

我们不都是吗?

我建议使用 ORM(iBatis、Hibernate、Toplink 等)。不要实现自己的 DAO。

【讨论】:

这里的问题是我们“应该”与一个 Web 服务层进行交互,而不是绕过它直接访问数据库。有没有可以处理 Web 服务的 ORM? p.s.我讨厌网络服务 @matt b:您的草图显示“业务级对象 DAO”。你是说这个草图不完整?请更新草图以显示真实情况,包括您的 Web 服务层。 DAO 与 Web 服务进行通信。 DAO 只是一种模式 - 一个检索另一个模式的对象 - 因此它们连接到 SQL 数据库就像连接到 Web 服务一样有效。

以上是关于打破业务逻辑和数据层似乎重叠的最佳设计? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

大数据处理方法的最佳设计模式

业务逻辑和数据访问层的循环依赖

CakePHP 业务逻辑层

如何在业务逻辑层设计数据传输对象

MVC设计模式与三层架构

业务层和表示层之间的依赖注入