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

发布于 2024-07-06 17:19:47 字数 882 浏览 7 评论 0原文

我在 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”,这是不允许的。 有人能帮我纠正一下吗?

I'm using the following code within the JCProperty class to retrieve data from a 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

This works fine but requires that the DAL object (JCPropertyDB) is aware of the business object (JCProperty) and I effectively create and populate the same object twice (once in the DAL to return to the BL and then again within the BL object to populate itself).

I'm missing something here, I know there must be a better way!

Effectively I need to assign 'Me = x' which is not allowed. Can someone put me straight?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

陌上青苔 2024-07-13 17:19:47

你的路线是正确的,但稍微遗漏了一点。

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

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

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

我建议查看Martin Fowler 的企业应用程序架构模式以了解数据访问模式。

You are on the right lines however missing one point slightly.

Typically, your Data Access Layer (DAL) would return Data Transfer Objects (DTO) from your database. These are Plain Old CLR Objects (POCO) which contain no business logic, simply properties more or less mapping to the database tables.

You would then have code which creates a Domain Model from these DTOs, referred to as a Data Mapper. The classes in the Domain Model might have similar names (i.e. CustomerDTO -> Customer) but in addition to the data, they will contain validation rules and possibly other business logic.

It is this Domain Model that you then use in your business layer, not the actual DTOs. This means that if you change the DTOs returned from the DAL (i.e. by implementing a new ORM tool), you only have to modify your Data Mapper providing the data model stays the same.

I recommend looking at Martin Fowler's Patterns of Enterprise Application Architecture for data access patterns.

苍风燃霜 2024-07-13 17:19:47

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

Not sure if this will answer your question, but the important point is that the domain model is independent of display and independent of storage. This is often denoted as separation of concerns. The idea is to get loose couplings and create a simple system where objects do not have several completely different responsibilities.
So what I would do, is to allow the DAL to create business objects directly, but make sure I don't contaminate my business objects with anything related to the DAL. Similarly I don't want to contaminate them with UI-specific things like HTML.
In my opinion it's ok that both the business layer, DAL and UI-layer all have dependencies to the domain model, however it's not ok to have dependencies from the domain model and into these other components.
To loosen the couplings, using something Spring or any other Dependency injection container together with interfaces and wiring can help you.
By recreating the same object in every layer you are violating the DRY principle (Don't repeat yourself) and you are introducing boiler plate code and increasing the chance of introducing an error somewhere.

墨洒年华 2024-07-13 17:19:47

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

class JCProperty : inherits JCPropertyDB
   {

   New()
      {
      MyBase.New()

      GetProperty(PropertyID)

      }
   }

然后你基本上就完成了,直到 JCProperty 类中有一些附加功能需要发生在 JCPropertyDB 中已有功能的“之上”。 然后,您重写 JCPropertyDB 方法以首先调用基本方法,然后添加新功能。

罗恩

Personally, I'm lazy. I usually do something like:

class JCProperty : inherits JCPropertyDB
   {

   New()
      {
      MyBase.New()

      GetProperty(PropertyID)

      }
   }

Then you're basically done, until you have some additional functionality in the JCProperty class that needs to happen "on top" of the functionality already existing in JCPropertyDB. Then you override the JCPropertyDB methods to call the base method first then add your new functionality.

Ron

野鹿林 2024-07-13 17:19:47

我一直在通过桥接模式和提供者模型从 DAL 接收 BO 并发回 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;
    }
}

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

I've been taking in BOs and sending back BOs from in the DAL via the bridge pattern and provider model. I can't see the point of DTOs unless I was fearful of heavy serialization (say a web service or JSON). My approach has been to abstract the Data-Layer and Business layer via an interface and provide an anonymous data layer fed into the business object. This means that I can plug in any data-layer, implement an interface that has universal Load and Save methods and which is then accessible via my domain layer. There is no DAL code in the BL - simply a call to a provided and abstracted data-layer. My call to the data layer is managed by a provider pattern (no direct reference) and I simply do:

public class Person : IBusinessObject<Person>
{
   protected IDataLayer<T> dataLayer;

   Person Load() { this.dataLayer.Load(this); }

}

in the data-layer I have...

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

I still don't know if this is good but it works quite well for me. I've managed to get lazy load in as well for nested objects using reflection.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文