在设计服务层时,我应该在接口合同中使用我的域对象吗?例如:
public void registerUser(String username,String realName)
VS
public void registerUser(用户用户)
域对象应该在客户端代码中构建还是在服务外观后面构建?
我正在使用EJB,我的客户端将是本地部署的Web应用程序,RMI客户端,也可能是Web服务客户端。
答案 0 :(得分:5)
从技术上讲,使用一个或另一个没有问题:通过XSD的Web服务能够支持像Strings这样的原始类型和像User类这样的复杂对象。
现在,如果您的User
课程有20个属性而您只需要username
和realName
来注册用户,该怎么办?在这种特殊情况下,最好使用第一种方法,因为需要更少的带宽,而不是强迫客户构建不需要的大型XML文档。
其他情况是您的User类根据JAXB规则生成复杂且高度嵌套的XML文档。这可能会为您的客户端以及复杂的客户端实现生成复杂的消息。如果是这种情况,您可以使用更简单的域类版本 - 可以使用一个或两个嵌套级别 - 作为DTO来简化消息交换。
答案 1 :(得分:1)
在我看来,Service层一般不应该使用域对象。域是处理业务逻辑,规则和工作流的东西,而服务则提供接口。
设计服务层时最简单的原则是“服务方法实现了单一用例”。 (用例是一个很好地定义了输入和输出的场景)。
在你的样本中 - registerUser(String username, String realName)
- 看起来完全正常。服务将实例化所有必需的域对象并启动业务操作 - 同时,服务客户端不知道业务逻辑内部(例如,用户对象构造中可能存在某些特定内容等)
答案 2 :(得分:0)
将User对象传递给所有服务似乎没有任何害处。根据DDD(领域驱动设计http://en.wikipedia.org/wiki/Domain-driven_design),这是一个非常好的做法,您的所有域对象应该可以在项目的所有层中使用。从长远来看,它将使您的代码更加面向对象,这通常在典型的Java EE项目(也称为贫血域模型)中看不到,但唯一的另一个建议是您尝试将业务逻辑保留在User类中并且 not 在您的服务中。
答案 3 :(得分:0)
将域对象作为服务层的一部分传递是一种更简单,更面向对象的方式。 使用用户输入值和构建相关的域对象 - 是控制器层的责任
此外,服务层描述了最终客户端使用的API。如果服务层开始使用泛型类型(如String,Maps等)公开API,则会出现问题。
而不是作为anti-pattern域对象的DTO,可以更好地从Controller层传递到服务层。
答案 4 :(得分:0)
在我看来,不适合从外观层公开域对象。使用该服务的客户端不应该依赖于域对象。最好设计一个数据契约并从外观层公开它们。它们将仅用于传输数据,即DTO。 考虑到域对象不仅仅是DTO,它们可以提供一些无功能。 外观层中的服务也暴露了系统的使用,它可能包括多个域对象的某些部分的协作,有时在外观层和可用域对象中方法的要求之间可能没有合适的映射。 此外,由于网络性能原因,DTO及其结构可能需要考虑一些因素。这些注意事项通常在设计域对象时没有意义。
答案 5 :(得分:0)
域对象应该在客户端代码中构建还是在后面构建 服务门面?
应在服务端创建域对象。客户端仅传递创建对象所需的所有参数。
对象构造的一般算法是:
如果在客户端创建了一个对象并将其传递给服务,则会出现几个问题: