【问题标题】:Passing data between business layer and data access layer - bad code?在业务层和数据访问层之间传递数据 - 错误代码?
【发布时间】:2010-09-16 16:34:29
【问题描述】:

我在 JCProperty 类中使​​用以下代码从 DAL 中检索数据:

Dim x As JCProperty
        x = JCPropertyDB.GetProperty(PropertyID)

        If Not x Is Nothing Then
            Me.PropertyID = x.PropertyID
            Me.AddressLine1 = x.AddressLine1
            Me.AddressLine2 = x.AddressLine2
            Me.AddressLine3 = x.AddressLine3
            Me.AddressCity = x.AddressCity
            Me.AddressCounty = x.AddressCounty
            Me.AddressPostcode = x.AddressPostcode
            Me.TelNo = x.TelNo
            Me.UpdatedOn = x.UpdatedOn
            Me.CreatedOn = x.CreatedOn
            Me.Description = x.Description
            Me.GUID = x.GUID
        End If

这工作正常,但要求 DAL 对象 (JCPropertyDB) 知道业务对象 (JCProperty),并且我有效地创建和填充相同的对象两次(一次在 DAL 中返回到 BL,然后再次在 BL 中对象填充自身)。

我在这里遗漏了一些东西,我知道一定有更好的方法!

实际上,我需要分配不允许的“Me = x”。有人能直截了当地说吗?

【问题讨论】:

    标签: .net vb.net data-access-layer


    【解决方案1】:

    你在正确的路线上,但稍微少了一点。

    通常,您的数据访问层 (DAL) 会从您的数据库返回 Data Transfer Objects (DTO)。这些是普通旧 CLR 对象 (POCO),不包含业务逻辑,只是或多或少映射到数据库表的属性。

    然后,您将拥有从这些 DTO 创建 Domain Model 的代码,称为 Data Mapper。领域模型中的类可能具有相似的名称(即 CustomerDTO -> Customer),但除了数据之外,它们还将包含验证规则和可能的其他业务逻辑。

    然后您在业务层中使用的是这个领域模型,而不是实际的 DTO。这意味着如果您更改从 DAL 返回的 DTO(即通过实施新的 ORM 工具),您只需修改您的数据映射器,前提是数据模型保持不变。

    我建议查看 Martin Fowler's Patterns of Enterprise Application Architecture 以了解数据访问模式。

    【讨论】:

      【解决方案2】:

      不确定这是否会回答您的问题,但重要的是域模型独立于显示和存储。这通常被称为关注点分离。这个想法是获得松散耦合并创建一个简单的系统,其中对象没有几个完全不同的职责。
      所以我要做的是允许 DAL 直接创建业务对象,但要确保我的业务对象不会被与 DAL 相关的任何东西污染。同样,我不想用特定于 UI 的东西(如 HTML)来污染它们。 在我看来,业务层、DAL 和 UI 层都对域模型具有依赖关系是可以的,但是从域模型和这些其他组件中具有依赖关系是不行的。
      要放松耦合,使用 Spring 或任何其他依赖注入容器以及接口和接线可以帮助您。
      通过在每一层中重新创建相同的对象,您违反了 DRY 原则(不要重复自己),并且您正在引入样板代码并增加在某处引入错误的机会。

      【讨论】:

        【解决方案3】:

        就我个人而言,我很懒惰。我通常会这样做:

        class JCProperty : inherits JCPropertyDB
           {
        
           New()
              {
              MyBase.New()
        
              GetProperty(PropertyID)
        
              }
           }
        

        然后您基本上就完成了,直到您在 JCProperty 类中有一些额外的功能需要在 JCPropertyDB 中已经存在的功能的“顶部”发生。然后覆盖 JCPropertyDB 方法以首先调用基本方法,然后添加新功能。

        罗恩

        【讨论】:

        • 正是我所缺少的!干杯。
        【解决方案4】:

        【讨论】:

          【解决方案5】:

          我一直在通过桥接模式和提供者模型接收 BO 并从 DAL 中发回 BO。我看不到 DTO 的意义,除非我害怕大量的序列化(比如 Web 服务或 JSON)。我的方法是通过接口抽象数据层和业务层,并提供一个匿名数据层馈入业务对象。这意味着我可以插入任何数据层,实现一个具有通用加载和保存方法的接口,然后可以通过我的域层访问该接口。 BL 中没有 DAL 代码——只是对提供的和抽象的数据层的调用。我对数据层的调用由提供者模式管理(没有直接引用),我只是这样做:

          public class Person : IBusinessObject<Person>
          {
             protected IDataLayer<T> dataLayer;
          
             Person Load() { this.dataLayer.Load(this); }
          
          }
          

          在我拥有的数据层中......

          public class PersonMapper : IDataLayer<Person> 
          {
              Person Load(Person person) {
              ...get DB stuff...map to person...decorate object...
                 return person;
              }
          }
          

          我仍然不知道这是否好,但它对我来说效果很好。我还设法为使用反射的嵌套对象实现延迟加载。

          【讨论】:

            猜你喜欢
            • 2020-11-28
            • 2021-02-11
            • 2011-12-27
            • 2012-11-27
            • 1970-01-01
            • 2010-11-18
            • 2019-05-08
            • 2012-08-30
            • 2012-07-06
            相关资源
            最近更新 更多