我知道 DTO 不是 ViewModel。误用时用法可以相同,但起源目的不同。
我将域实体从我的存储库返回到服务。在我的服务中,由于表格视图的需要,我必须重塑实体。
现在我有一个冲突。通常我的服务会返回一个带有数据的 DTO,但在这种情况下,由于表示层的需要,数据会被重新整形。有人可能会说 DTO 是一个 ViewModel,但我不想从我的服务中返回一个 viewmodel。
在这种情况下,DTO 是一个 ViewModel,好的行为丢失了,但是如果没有进一步的行为怎么办。
这里不对劲。
我知道 DTO 不是 ViewModel。误用时用法可以相同,但起源目的不同。
我将域实体从我的存储库返回到服务。在我的服务中,由于表格视图的需要,我必须重塑实体。
现在我有一个冲突。通常我的服务会返回一个带有数据的 DTO,但在这种情况下,由于表示层的需要,数据会被重新整形。有人可能会说 DTO 是一个 ViewModel,但我不想从我的服务中返回一个 viewmodel。
在这种情况下,DTO 是一个 ViewModel,好的行为丢失了,但是如果没有进一步的行为怎么办。
这里不对劲。
感觉可能太多了,但不要忽视,现在可能正好与您想要在服务和 UI 级别生成的内容完全匹配。将这两部分分开但几乎相同并没有本质上的错误。
通常,ViewModel 会进一步扩展以支持计算字段、UI 选择选项等。在无需破坏您的服务(以及依赖它的任何人)的情况下,在路上扩展该不同的对象总是会更容易。
另一方面,我真的很喜欢跟随 YAGNI。所以,如果你真的相信这个物体不可能生长,回收一些东西并不总是很糟糕。(更多的上下文肯定有助于打这个电话)。
最后,不要花太多时间在它的学术上。你似乎对你想要完成的事情有一个很好的处理,唯一好的代码是交付的代码。编写测试,分离你能做的,但把代码拿出来。我见过一些项目因为过度设计而失败。
干杯。
我感觉到你的痛苦。我不使用“存储库”模式,但是我的服务层将 DTO 返回到我的控制器,然后在某些时候填充我的 ViewModel 中的大部分或至少一些属性。有时这似乎有些矫枉过正,并且总是提出“这是做事的最佳方式”的问题,从我被告知和研究的结果来看,答案是“是”。
我建议您在控制器中有一个 PresentationService ,该对象负责返回您的视图模型。然后,您的演示服务使用域服务、数据服务或您的存储库,或者您需要的任何其他东西来将数据聚合到您的视图模型。
如果来自数据库的形状是您想要的,那么您可以使用 DTO 作为视图模型,但如果不是,并且您有其他类型的数据投影,那么演示服务是一个很好的做法。