Java 将数据对象结构和字段隐藏到WebServices客户端

Java 将数据对象结构和字段隐藏到WebServices客户端,java,web-services,api,design-patterns,Java,Web Services,Api,Design Patterns,我们有一个在控制器/服务/DAO体系结构上用Java开发的经典订单管理应用程序。数据对象是表示数据库中数据的POJO。基本上,我们有一个类映射数据库中的一个表,但我们不使用任何ORM或实体机制。这些数据对象在所有层之间传递,以通过Web GUI创建/修改/获取订单。 该应用程序还有一个WebService层,允许外部系统通过SOAP管理这些订单。WebService层依赖于服务层来确保WebService和GUI之间使用相同的逻辑 我们试图使WebServicesAPI尽可能稳定,但是,由于我们

我们有一个在控制器/服务/DAO体系结构上用Java开发的经典订单管理应用程序。数据对象是表示数据库中数据的POJO。基本上,我们有一个类映射数据库中的一个表,但我们不使用任何ORM或实体机制。这些数据对象在所有层之间传递,以通过Web GUI创建/修改/获取订单。 该应用程序还有一个WebService层,允许外部系统通过SOAP管理这些订单。WebService层依赖于服务层来确保WebService和GUI之间使用相同的逻辑

我们试图使WebServicesAPI尽可能稳定,但是,由于我们目前正在使用数据对象作为WebService方法的参数,该API可能会频繁更改(至少每次我们拥有或修改数据库中的任何字段时)。此外,我们希望向WebService客户端隐藏数据库结构的一些复杂性。例如,数据库包含多个我们想对客户端隐藏的字段

具体问题:

  • 通常使用什么样的设计模式来隐藏数据库 通过客户端API的结构和字段

  • 有什么好的实践来处理公共服务之间的“映射”吗 方法参数和内部数据对象

  • 数据传输对象是我问题的答案吗


您不应该跨流程边界传递数据对象。它使应用程序变得脆弱,并保证每次更改模式时都要进行大量返工。我的建议是:

-数据访问层应该是这样的:处理创建、读取、更新和删除数据库对象。DAL的用户必须知道数据库如何工作才能使用它

ex(在psuedo代码中):

等 -服务层转换数据库模式以隐藏复杂性,并对试图使用这些数据制作应用程序的开发人员真正有用的内容发表意见

例:

您可以决定是否包含该ID。您可能会决定更改字段名的大小写,并且您可能会将数据投影到一个对应用程序开发人员更有意义、比数据库模式更稳定的表单中。也许你漏掉了很多东西,所以通过网络传输的数据就少了。诸如此类

DBA的任务是创建一个性能良好的数据库,并通过规范化最大化存储。这与服务层的目标不同,服务层并不期望其调用的结果被持久化

不同的体系结构对视图模型有不同的名称(我称之为视图模型)。DTO是另一个名称

我们试图使WebServicesAPI尽可能稳定,但是 我们的数据对象被用作WebService方法的参数, 该API可能会频繁更改

你已经走错了路。Web服务是以平台无关的方式实现互操作性和集成。

传递给Web服务的所有对象都应该是“数据持有者”,并且应该与您的业务逻辑无关。您应该使用转换器将这些“数据持有者”映射到应用程序所需的实际类

回答我自己的问题:

我们显然面临着向公共API公开结构化数据的问题。这些数据来自内部管理的域模型(数据对象),但域模型不能直接通过公共API公开

相反,必须创建和维护另一组类,通常称为数据传输对象(DTO)或视图模型,以用作公共API的输入/输出参数。使用这种DTO,域模型可以在不修改公共API的情况下进行更改,并且公共API可以以一种非常可控的方式进行更改


某些映射(也称为绑定)必须在域模型和DTO之间的应用程序中维护。通常是双向的。可以找到大量Java mapper/binder库

我知道分离层和最小化依赖关系是一种很好的模式,但是拥有两个独立的域模型不是要做很多工作吗?是的,这需要做更多的工作,但仅限于您,而不是所有依赖于服务输出的客户端。对他们来说,工作要少得多,而且他们不必了解您的数据模型就能使用您的结果。对于持久性存储和召回,数据模型有完全不同的要求。域模型将问题概念化为客户可以理解的内容。这和说做一个UI而不是仅仅给SQL访问权是“更多的工作”是一样的。谢谢你的回答。这让我意识到,我们确实需要一组新的类,以便域模型可以在不更改公共API的情况下更改。考虑到这一点,我在谷歌上找到了我真正想要的,并且我能够回答我自己的问题。谢谢你的回答。我完全同意这是个问题,这是我问题的一点。这些“数据保持器”和“转换器”是什么?我们应该实现什么样的设计模式,因为随着应用程序的发展,我们会有很多这样的设计模式?对于重新给出我的答案,然后认为它是正确的,我们投了反对票。来吧,伙计
Person = {
PERSON_ID:'1234567jksjgkhsduw0909wueioksgt',
FIRST_NAME:'CHRIS',
LAST_NAME:'MCCALL',
TITLE:'',
GENDER:'M',
LAST_NAME_SUFFIX:null,
Addresses = [{ADDRESS_ID:1234,...}]
}
Person = {
name:'Chris McCall',
primary_address:'123 Main St',
secondary_address:null
}