- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个丰富的域模型,其中大多数类具有某些行为和某些属性,这些行为和某些属性是经过计算或公开的成员对象的属性(也就是说,这些属性的值永远不会保留)。
我的客户仅通过WCF与服务器对话。
这样,对于每个域实体,我都有一个对应的DTO(仅包含数据的简单表示形式),以及一个实现DtoMapper<DTO,Entity>
并可以通过将实体转换为其DTO等效项的映射器类,反之亦然静态网关:
var employee = Map<Employee>.from_dto<EmployeeDto>();
最佳答案
我个人建议将映射保留在服务器端。到现在为止,您可能已经做了很多工作来构建设计。不要扔掉它。
考虑什么是Web服务。它不仅是对您的ORM的抽象;这是合同。它是内部和外部客户的公共API。
公共API应该几乎没有任何理由要更改。除了添加新的类型和方法外,对API的几乎所有更改都是一项重大更改。但是您的域模型不会那么严格。在添加新功能或发现原始设计中的缺陷时,您将需要不时更改它。您希望能够确保对内部模型的更改不会导致通过服务合同进行级联更改。
实际上,由于类似的原因,为每条消息创建特定的Request
和Response
类是一种常见的做法(我不会用“最佳做法”来侮辱读者)。扩展现有服务和方法的功能变得更加简单,而又不会破坏更改。
客户可能不希望您在服务内部使用完全相同的模型。如果您是唯一的客户,那么这似乎是透明的,但是如果您有外部客户,并且已经看到他们对系统的解释通常相差甚远,那么您将了解不让完美模型泄漏的价值超出服务API的范围。
有时,甚至不可能通过API发回模型。发生这种情况的原因有很多:
在对象图中循环。 OOP非常好;序列化的灾难。最后,您不得不为必须串行化图形的“方向”做出痛苦的永久性选择。另一方面,如果您使用DTO,则可以按照所需的任意方向进行串行化,无论适合什么任务。
尝试在SOAP / REST上使用某些类型的继承机制充其量不过是一种麻烦。旧式XML序列化程序至少支持xs:choice
; DataContract
不会,我也不会质疑其基本原理,但是只要说您的富域模型中可能存在某种多态性就可以了,这简直是不可能实现的。
延迟/延迟加载,如果您使用ORM,则可以利用它。确保将其正确序列化非常尴尬-例如,使用Linq to SQL实体,WCF甚至不会触发惰性加载器,除非您手动加载,否则它只会将null
放入该字段中-但问题会对于返回的数据更糟。像在构造函数中初始化的List<T>
自动属性那样简单(在域模型中很常见),根本无法在WCF中使用,因为它不会调用构造函数。相反,您必须添加[OnDeserializing]
初始值设定项方法,并且您确实不想用此垃圾弄乱您的域模型。
我还刚刚注意到您在使用NHibernate的括号中的注释。考虑到像IList<T>
这样的接口根本无法通过Web服务进行序列化!如果像我们大多数人一样,将NHibernate与POCO类一起使用,那么这段时间根本就行不通。
当内部域模型完全不符合客户端需求时,很可能会有很多实例,并且更改域模型来满足这些需求是没有意义的。举个例子,让我们简单地处理发票。它需要显示:
有关帐户的信息(帐号,名称等)
发票专用数据(发票编号,日期,到期日等)
应收帐款信息(以前的余额,滞纳金,新的余额)
发票上所有内容的产品或服务信息;
等等。
这可能适合领域模型。但是,如果客户希望运行显示1200张发票的报表怎么办?某种对帐报告?
这很糟糕,需要序列化。现在,您将发送1200份发票,其中一遍又一遍地序列化相同的数据-相同的帐户,相同的产品,相同的应收账款。在内部,您的应用程序正在跟踪所有链接。它知道35号发票和45号发票是针对同一客户的,因此共享Customer
参考;所有这些信息在序列化时都会丢失,最终您将发送大量的冗余数据。
您真正想要的是发送包含以下内容的自定义报告:
报告中包括的所有科目及其应收账款;
报告中包括的所有产品;
所有发票,仅包含产品和帐户ID。
如果要避免大量冗余,则需要先对传出数据执行其他“规范化”,然后再将其发送到客户端。这在很大程度上有利于DTO方法。在您的域模型中使用这种结构是没有意义的,因为您的域模型已经以其自己的方式处理了冗余。
我希望这些例子和理由足以说服您保持完整的Domain <-> Service Contract映射。到目前为止,您已经做对了绝对正确的事情,拥有了出色的设计,并且将所有这些努力全部取消而取而代之的是一种可耻的行为,而这可能会导致以后引起很多头痛。
关于.net - 是否应该在客户端和服务器端都将DTO映射到域实体或从域实体映射DTO?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2201150/
我看到 DTO 类型在域模型中的类型内创建并在类型之间传递。这是好习惯吗? 我一直认为 DTO 主要用于上下文边界(即对象图的边缘)以解耦上下文实现(例如域/ui 边界)。 最佳答案 你的问题有点主观
我们将使用 DTO 向表示层发送数据或从表示层发送数据。我们有这样的层: 外观 应用服务 域名 我们使用 Dozer 来帮助我们将实体转换为 dto。但我现在有两个问题: 从entity到dto我们可
我对术语有疑问。根据 Fowler 的说法,DTO 是“在进程之间传输数据以减少方法调用次数的对象”。 (http://martinfowler.com/eaaCatalog/dataTransfer
我们使用 spring-boot 开发的应用程序遵循微服务架构。为了解释这个问题,让我们考虑 3 个不同的服务 A、B、C。服务 A 和 B 也使用服务 C 的一些 API。 我在项目 C(服务 C)
所以基本上我正在编写一个使用 DTO 的 API,但我在返回 DTO 内的另一个实体时遇到了问题。 这是我的 DTO: public class DirectoryDTO { String per
我尝试从方法响应正文中获取派生类字段。请求体参数是基类的类型。请求带有派生类字段,但我无法将其转换为派生类。 这是我的 Controller 方法和 DTO 类: 方法: @PostMapping(
这更多的是一个理论问题,而不是一个实际问题。 我们有一个分层架构,类似于: UI UI_JavaHandler Backend DTO1 需要比 DTO2 多一点的数据,并且恰好是一个额外的字符串
我在 Wildfly 10.1.0-Final 上使用带有 Java 8 和 Hibernate (5.0.X) 的 Java EE 7,我需要使用投影将 JPQL 查询结果加载到 DTO 中,但我找
有一个建议是transfer objects should not contain object references to other transfer objects .相反,他们应该使用其他传输
我们正在开始一个新项目并正在设计 DTO,这些 DTO 将被注入(inject)到具有行为的相应 POCO 中。然而,我能找到的每个 DTO 示例都只包含值类型,例如: public class Cu
这可能是一个一般的java问题 DTO1 属性1 属性2 属性3 DTO2 属性1 属性2 属性3 属性4 属性5 属性6 属性7 属性8 属性9 属性10 属性11 属性12 我将在屏幕上的 gxt
我在一个项目中遇到了一个问题,并在一个裸测试项目中成功地重现了它。 我有以下 dto: public class AppUserDto { public int Id { get; set;
我正在研究 RESTful API,但在为 API 提供输入的过程中遇到了一些麻烦。 假设我有一个可以像这样获取的“人”资源:api/person/{id}并返回一个这样的对象: public cla
我正在使用 DTO 构建我的第一个应用程序 - 我目前有一个 DTO 用于获取特定对象的数据,另一个不同的 DTO 用于更新(PUTting)数据 - 因为只有少数字段可以从任何客户端更新,我决定为
private void writeData(HSSFSheet sheet) { for (int i = 0; i 并动态获取 DTO 属性值?,我们在Stack Overflo
我正在尝试使用 Jackson 和 Kotlin 将 YAML 文档映射到复杂的 DTO 结构,但似乎在某处遇到了误解。 我正在解析的 YAML 文档是 item_names: - item:
这个问题在这里已经有了答案: How to efficiently create a list of objects inside of a generic method? (2 个答案) 关闭 9
我们将使用 DTO 向表示层发送数据或从表示层发送数据。 我在名为 PostAd 的服务对象上有一个方法,它发布用户输入的广告。 Ad 与另一个名为 AdValues 的对象相关联,该对象包含 Ad
我的应用程序服务中有验证逻辑,用于确定请求的操作是否成功,如果没有,原因。我质疑这是否是代码异味,因为它在应用程序服务中而不是域服务中,它围绕检查域模型是否存在、dto 中的属性是否可以为空等展开。代
我有以下域模型: public class Playlist { public long Id { get; set; } public string Title { get; set
我是一名优秀的程序员,十分优秀!