业务对象和数据层

Posted

技术标签:

【中文标题】业务对象和数据层【英文标题】:Business Objects and Data Layer 【发布时间】:2011-04-12 06:34:55 【问题描述】:

这个网站为我提供了许多有用的答案,但是经过几个小时的搜索,我还没有找到任何专门满足我需求的东西。所以这里...

我工作的公司正在设计一个新的业务对象层和一个数据访问层——它们将驻留在不同的程序集中。

问题是我很难理解这两个层之间的交互 ​​- 具体来说,如果 DAL 知道 BOL,我已经阅读了许多文章说依赖顺序应该类似于这个:

GUI / 演示 --> BOL ---> DAL

但据我所知,DAL 需要对 BOL 的引用才能将对象“返回”到 BOL 层。

我打算在 BOL 和 DAL 之间建立一个中间组件,它基本上是一个填充了接口的薄层,以解耦这两个 DLL,因此如果需要,框架可以使用不同的 DAL。

这让我想到了引入另一个薄层,其中包含 BO 实现的一堆接口,然后当 BOL 调用 DAL 接口时,它会传递一个实现这些 BO 接口之一的对象,然后 DAL 继续执行填充对象。这消除了 BOL 和 DAL 之间的所有依赖关系 - 但是,我发现说实话很难证明它的合理性。

理想情况下,我们希望使用 ORM,因为它只是消除了编写 CRUD 内容的需要,但我们的客户习惯于在他们的数据库中摆弄列长度,这是迄今为止我们使用强类型数据表。我听说 Linq2SQL 还在编译时存储列长度,不确定 NHibernate 是否这样做(但是,我不确定我们的数据库模式是否为 NHibernate 设计得足够干净,处理遗留系统的陷阱)。

所以,是的,任何关于 BOL 和 DAL 之间关系的见解都非常受欢迎 - 如果上面写得不好,我们深表歉意,如果有人需要澄清,我很乐意提供更多细节。

马龙

【问题讨论】:

【参考方案1】:

我这样做的方式是 BO 期望 DataReaderDataContext 或从 DAL 返回的任何内容,而不是实际形成的对象。然后 BO 层的工作就是从返回的对象中获取并填充自己。 DAL 不会返回已完成的 BO。需要记住的主要一点是,更改 BO 层中的某些内容不会导致 DAL 层出现问题,但更改 DAL 层中的某些内容可能会导致 BO 层出现问题。

我通常做的一个简短的例子

在BO层

FillData()
   DataReader dr = DataLayer.GetData("SomePropertyForAStoreProcedure");
   If dr.Read()
    Property1 = dr.GetValue("Property1");
    //So on and so forth
   

在 DAL 中

DataReader GetData(String SPProperty)


【讨论】:

【参考方案2】:

看看 SubSonic http://subsonicproject.com/ 它为您完成大部分数据访问繁琐的工作,并且比大多数 ORM 更容易

【讨论】:

【参考方案3】:

DAL 需要对 BOL 的引用,以便它可以填充对象。您不希望有任何从 BOL 到 DAL 的引用或耦合 - 这样做会导致您的 BOL 耦合到特定的数据库实现。当您考虑它时,这是有道理的。您的 DAL 知道有关业务对象的详细信息,直至属性级别以及如何从数据库中检索它们的数据 - 当然 DAL 本质上与 BOL 紧密耦合。所以这种方式的参考很好。如果你想一想,另一边是什么?数据库。从对象数据到数据库的“紧密耦合”?是的,它非常紧。这个概念甚至不是很有意义。

这是您需要解耦的所有其他方向。所以是的,只要没有从 DAL 直接耦合到 BOL,您就可以随意更改您的数据平台。

在这种情况下,为 BO 创建接口并将它们传递给 DAL 并没有多大意义。但是,您有时可能需要另辟蹊径。通常,业务对象不必知道它们是如何创建或持久的。

在实践中,即使使用大多数 ORM,例如,创建一个完全没有任何类型的持久性工件的业务层也会变得非常困难,有时实际上是不可能的。因此,有时您会遇到一些难以解决的问题,并且您可能会发现严格避免在 BO 中掌握任何数据知识会导致您过度复杂化,从而降低而不是增加价值。

如果您觉得没有更好的方法,并且需要在 BOL 中保留一些内容,请创建一个简单的接口,以便可以将 DAL 功能传递到 BOL。这样,您至少仍然可以使 BOL 与特定的数据库实现分离。

另外,虽然这是很多额外的工作,除非这是一个非常简单的一次性应用程序,否则我强烈建议您在 UI 和 BOL 之间再添加一层。 MVP(Model-View-Presenter)模式是一种通用设计模式,用于减少核心应用程序和 UI 之间的耦合。 Presenters 有很多变种,不要太拘泥于具体细节,没用过的就从简单的 MVP 开始吧。

模式并没有那么难,只是 UI 本身太杂乱了,以至于您可能需要至少进行几次主要的迭代/应用程序,然后您才会觉得您所编写的代码在任何时候都可以系统地、有条不紊地工作解耦 UI。只要继续努力,开始掌握一系列技术,不要因为你还没有实现彻底的彻底分离而挂起电话。任何你学到和能做的事情,甚至对在 UI 上创建一个定义良好的边界都有一点贡献,这是朝着正确方向迈出的一大步。

【讨论】:

【参考方案4】:

“正确”方法会因业务需求而异。老实说,在许多项目中,我觉得旧式 ado 记录集比现在的许多 ORM 更容易维护。花一些时间来确定您的需求是什么,并记住开发时间和可维护性也是应该适当权衡的设计目标。

【讨论】:

【参考方案5】:

这还取决于您使用的是 if/what library/ORM(Object-Relational Mapper)。当使用(好的)ORM 时,DAL 应该是一个非常遥远的问题,因为它几乎完全被 ORM 隐藏;然而,最佳实践表明,即便如此,对于中型到大型应用程序,您应该在 BOL 和 ORM 之间引入另一层,通常是 DTO(数据传输对象)。 DTO 也可以在没有 ORM 的情况下使用,因为它们只是在单独的库中定义的哑对象,并且 DAL 可以负责持久化它们(将它们从/转换到数据库结构),而 BOL 可以查询 DAL 并接收那些对象。

可以通过多种方式实现层的解耦,最常见的是通过接口和/或 MEF 或其他 DI/IOC 框架。如果有效使用,任何此类技术都可以实现足够的解耦。

此外,根据所使用的技术,正如 Sisyphus 所说,其中一种分层架构模式将有助于很好地分离关注点:MVC、MVP、MVVM 等。我个人推荐 MVVM 与 WPF(桌面)或 Silverlight(Web),但我'我有很大的偏见 - 即我爱死他们两个:)

【讨论】:

【参考方案6】:

这是我的发现, 1. 使用接口 2. 在 DAL 和 BLL 之间使用 DTO [数据传输对象] 3. BLL一分为二,a. BLL b. Service Layer 4.使用控制反转(IoC)容器保持耦合尽可能低。

【讨论】:

以上是关于业务对象和数据层的主要内容,如果未能解决你的问题,请参考以下文章

面向对象——三层架构(表现层业务层持久层)

数据访问层和业务对象

业务逻辑是不是属于服务层?

业务层拆解和业务对象类型

什么对象应该从数据访问层返回到业务层一个n层系统

具有业务对象、DTO 和实体/域对象的数据转换模式