2

在设计服务层时,我应该在接口契约中使用我的领域对象吗?例如:

公共无效注册用户(字符串用户名,字符串实名)

VS

公共无效注册用户(用户用户)

域对象应该在客户端代码中还是在服务外观之后构建?

我正在使用 EJB,我的客户端将是本地部署的 Web 应用程序、RMI 客户端,也可能是 Web 服务客户端。

4

6 回答 6

5

从技术上讲,使用一个或另一个没有问题:通过 XSD 的 Web 服务能够支持像字符串这样的原始类型和像用户类这样的复杂对象。

现在,如果你的User类有 20 个属性,而你只需要usernamerealName注册一个用户怎么办?在这种特殊情况下,最好使用您的第一种方法,因为如果您不强迫您的客户端构建不需要的大型 XML 文档,则需要更少的带宽。

其他情况是您的 User 类根据 JAXB 规则生成复杂且高度嵌套的 XML 文档。这可以为您的客户和复杂的客户实现产生复杂的消息。如果是这种情况,您可以使用域类的更简单版本(可能具有一两个嵌套级别)作为 DTO 来简化消息交换。

于 2012-05-21T01:23:15.090 回答
1

在我看来,服务层一般不应该使用域对象。域是处理业务逻辑、规则和工作流的东西,而服务提供了一个接口。

设计服务层时最简单的原则是“服务方法实现单个用例”。(用例是一个输入和输出都定义得很好的场景)。

在您的示例中 - registerUser(String username, String realName)- 看起来非常好。服务将实例化所有需要的域对象并启动业务操作 - 同时,服务客户端不知道业务逻辑内部(例如,可能有一些特定的用户对象构造等)

于 2012-05-21T13:23:13.887 回答
0

在您的所有服务中传递 User 对象似乎没有什么害处。根据 DDD(域驱动设计http://en.wikipedia.org/wiki/Domain-driven_design),这是一个非常好的做法,您的所有域对象都应该在项目的所有层中可用。从长远来看,它将使您的代码更加面向对象,这通常在典型的 Java EE 项目(又名贫血域模型)中被视为缺乏,但唯一的额外建议是您尝试将业务逻辑保留在 User 类中,而不是在您的服务中.

于 2012-05-22T09:29:49.407 回答
0

将域对象作为服务层的一部分传递是一种更简单且更面向对象的方式。使用用户输入值并构造相关的域对象 - 是控制器层的职责

此外,服务层描述了最终客户端使用的API。如果服务层开始使用泛型类型(如字符串、地图等)公开 API,那么麻烦就开始了。

而不是 DTO,它是一种反模式,域对象可以更好地从控制器层传递到服务层。

于 2012-05-22T11:23:12.567 回答
0

在我看来,从门面层暴露领域对象是不合适的。使用该服务的客户端不应依赖于域对象。最好设计一个数据合约并将它们从外观层公开。它们将仅用于传输数据,即 DTO。考虑到域对象不仅仅是 DTO,它们可以提供一些无功能的东西。此外,外观层中的服务暴露了系统的使用,它可能包括多个领域对象的某些部分的协作,有时可能在外观层中的方法的需求和可用的领域对象之间没有合适的映射。此外,出于网络性能的原因,DTO 及其结构可能需要考虑一些因素。而这些考虑在设计领域对象时通常没有意义。

于 2014-02-10T10:53:13.870 回答
0

域对象应该在客户端代码中还是在服务外观之后构建?

域对象应该在服务端创建。客户端仅传递创建对象所需的所有参数。

对象构造的一般算法是:

  1. 获取参数
  2. 验证参数
  3. 将有效参数传递给对象构造函数以获取有效对象
  4. 在存储库中注册一个有效的构造对象以进行持久性(如有必要)

如果在客户端创建一个对象并传递给服务,那么会出现几个问题:

  1. 来自客户端的对象可能处于不正确的状态(客户端数据不可信)
  2. 必须验证对象状态
  3. 对现有对象的验证意味着验证逻辑的可能重复,在验证私有字段值时可能会丢失封装,或者有时违反单一责任原则
  4. 有时服务必须使用传递的对象属性值作为参数来重建对象
于 2015-05-23T15:46:37.223 回答