使用DTO是解决这个问题的最好方法吗?

发布于 2024-09-30 15:44:25 字数 1374 浏览 0 评论 0原文

我正在开发一个客户端/服务器系统:

有一个数据库、一个应用程序服务器和一个用户界面(客户端)应用程序。应用程序服务器处理来自客户端应用程序的连接,当客户端应用程序请求用户列表或通过 ID 请求特定对象时,客户端应用程序又与数据库进行通信。

目前我有一组数据对象,如“用户”、“区域”等,它们映射到数据库中的表。这些数据对象在共享库中定义,该共享库在编译时链接到客户端和应用程序服务器。它们继承一个允许它们序列化的类,以便它们可以在客户端和服务器之间传递,并且它们采用“数据提供者”作为依赖项注入,以允许提交发送到应用程序服务器或发送到数据库,具体取决于是否它们在客户端或服务器端使用。

当客户端应用程序的用户想要编辑用户时,它会从应用程序服务器请求该对象,使用它用当前值填充用户界面,允许用户编辑这些值,然后“提交”回该对象到应用程序服务器,应用程序服务器又将其提交到数据库。

这对于这个非常简单的场景来说很好,但是随着它变得更加复杂,用户界面将需要可能由几个底层数据库对象组成的对象,所以我想我需要在某种程度上从数据库模型中抽象出来。

在这种情况下,我不应该将我认为所谓的“DAL”对象传递到用户界面(通过序列化),所以我想我需要一些 DTO(数据传输对象)。

我还发现在执行业务逻辑的应用程序服务中,我目前正在通过切换从客户端提交的对象类型,执行任何必要的操作,然后提交到数据库来处理这一切。我想也许在这里我需要业务对象,每个对象都知道如何验证和操作。

所以我可能最终会得到:

Shared:
 * UserDTO (data transfer object)

Application Server:
 * UserDAL (data access object)
 * UserBO (business object, contains UserDAL)
 * UserDTO (data transfer object as defined in shared lib)

Client:
 * UserDTO (data transfer object as defined in shared lib)

因此,客户端请求用户 DTO,根据需要显示或更新,调用“保存”方法,它被序列化并发送到应用程序服务器,应用程序服务器对其进行反序列化,创建业务对象可以对其执行任何操作(例如验证、保存到数据库等)。

这意味着删除从 DAL 对象到 DTO 对象的所有序列化逻辑,并删除我的大型业务逻辑类,并且将阻止表示层(客户端)了解有关数据库结构的任何信息。

这听起来正确吗?

其他人确实建议将业务对象放在共享库中,而不是使用数据传输对象。但问题是我在两个地方都有业务逻辑,如果能够在一处更新业务逻辑就好了,而不是可能必须更新与一个应用程序服务通信的 100 个客户端应用程序。这还意味着业务对象还必须具有 DTO 对象的所有获取/设置例程。

我希望这是有道理的。任何想法将不胜感激:-)

I am working on a client / server system:

There is a database, an application server and a user interface (client) app. The application server handles connections from the client applications which in turn talks to the database when the client app requests a list of users for instance, or a particular object by id.

Currently I have a set of data objects like "user", "area", etc. which map to tables in the database. These data objects are defined in a shared library that gets linked into the client and the appserver on compile. They inherit a class that allows them to be serialised so they can pass between client and server, and they take a "data provider" as a dependency injection to allow the commit to either send to the application server or send to the database depending on if they're being used at the client or the server end.

When the user of the client app wants to edit a user, it requests that object from the app server, uses it to populate the user interface with the current values, allows the user to edit those values, and then "commits" the object back to the appserver which in turn commits it to the database.

This is fine for this very simple scenario, but as it gets more complicated the user interface will want objects that are perhaps consisting of several of the bottom layer database objects so I'm thinking I need to abstract away from the database model to some degree.

This being the case, I should not be passing what I suppose would be called "DAL" objects to the user interface (via the serialisation), so I'm thinking I need some DTOs (data transfer objects).

I'm also finding in the application service where I do the business logic, I'm currently handling it all by switching on the type of object being committed from the client, doing whatever is neccessary and then committing to the database. I'm thinking perhaps here I need business objects instead, which each object knowing how to validate and act.

So I'd perhaps end up with:

Shared:
 * UserDTO (data transfer object)

Application Server:
 * UserDAL (data access object)
 * UserBO (business object, contains UserDAL)
 * UserDTO (data transfer object as defined in shared lib)

Client:
 * UserDTO (data transfer object as defined in shared lib)

So, the client requests a user DTO, displays or updates as neccessary, the "save" method is called, it gets serialised and sent to the application server which de-serializes it, creates the business object which does whatever it likes with it (such as validate, save to DB, etc.).

This means removing all my serialisation logic from the DAL objects to the DTO objects, and removing my big business logic class, and would stop the presentation layer (client) having to know anything about the database structure.

Does this sound about right?

Someone else did suggest having the business objects in a shared library and not having data transfer objects. The problem with this though is I have business logic in 2 places, and it'd nice to be able to update the business logic in one place, rather than potentially having to update 100's of client apps talking to the one application service. It also means the business objects would have to also have all the get/set routines of the DTO objects.

I hope this makes sense. Any thoughts would be appreciated :-)

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

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

发布评论

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

评论(1

俏︾媚 2024-10-07 15:44:25

我最初的想法是 - 你的实际问题是什么?因为据我所知,你没有做错任何事。

是的 - 将多个对象放入 DTO 中,然后将其序列化以在客户端/服务器之间“通过线路”传输,这对我来说听起来很正确。

是的 - 拥有类型/业务对象的共享库就可以了;我假设它们只不过是没有逻辑的真正“愚蠢”的数据结构,并且它们不会经常改变。

<块引用>

所以我认为我需要在某种程度上从数据库模型中抽象出来。

是的。您可以在客户端和服务器之间执行相同的操作。如果您使用的是 Microsoft 平台/.Net,您可以使用 WCF,它允许不同类型的绑定,因此不再需要手动序列化。

<块引用>

问题是我在两个地方有业务逻辑

,在两个地方有它并不理想 - 但它确实有一些优点。在客户端复制一些业务逻辑(我在这里想到“验证”规则)的一个优点是,UI 可以为用户提供更具交互性的体验,因为他们不必等待来回告诉他们不能将自己的姓氏添加到电话号码字段中。您仍然需要在服务器端提供适当的验证和完整的业务规则:可以说是“纵深防御”。

My initial thought is - what's your actual problem? Because from what I can see you're not doing anything wrong.

Yes - putting multiple objects into a DTO, and then serializing that for transfer "over the wire" between client / server sounds right to me.

Yes - having a shared library of types / business objects is fine; I'm assuming they are nothing more than really 'dumb' data structures with no logic, and that they don't change often.

so I'm thinking I need to abstract away from the database model to some degree.

Yes. You could possibly do the same between client and server. If you were in using the Microsoft platform / .Net you could use WCF which allows for different types of binding, so no more manual serialization.

The problem with this though is I have business logic in 2 places

Yes havingit in two places is not ideal - but it does have some advantages. One advantage of duplicating some of the business logic at the client-end (I'm thinking of "validation" rules here) is that the UI could provide a much more interactive experience for users, in that they wouldn't have to wait for a round-trip to tell them they can't add their surname into the phone number field. You'd still provide proper validation and full business rules on the server-end: "defense in depth" so to speak.

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