在业务层和数据访问层之间传递数据 - 坏代码?

时间:2008-10-11 15:31:50

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

我在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'。有人可以直截了当地说出来吗?

5 个答案:

答案 0 :(得分:4)

你排在正确的位置,但稍微缺少一点。

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

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

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

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

答案 1 :(得分:2)

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

答案 2 :(得分:1)

就个人而言,我很懒。我经常这样做:

class JCProperty : inherits JCPropertyDB
   {

   New()
      {
      MyBase.New()

      GetProperty(PropertyID)

      }
   }

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

罗恩

答案 3 :(得分:0)

答案 4 :(得分:0)

我一直在接收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;
    }
}

我仍然不知道这是否好,但它对我来说效果很好。我已经设法使用反射对嵌套对象进行延迟加载。