评论此question后。我开始研究,但我仍然感到困惑。
实体在返回控制器之前应转换为Dto?对我来说这听起来不太实际。
答案 0 :(得分:46)
我们正在谈论软件架构,并且在谈论软件架构时,总有一千种方法可以做一些事情,并且有很多关于什么是最佳方式的意见。但没有最好的办法,一切都有利有弊。牢记这一点!
通常您有不同的图层:
通常,每个图层都会使用自己的对象:
这意味着每个图层只能使用自己的对象,并且永远不会将它们传递给另一个图层。
为什么?因为您希望每个图层与其他图层分开。如果要在控制器中使用实体,则演示文稿将取决于数据的存储方式。那太糟糕了。您的视图与数据的存储方式无关。它甚至不应该知道数据的存储方式。
想一想:您更改了数据库模型,例如:您向其中一个数据库表添加一个新列。如果将实体传递给控制器(或者更糟糕的是:控制器将它们公开为JSON),则对数据库进行更改会导致演示文稿发生更改。如果实体直接公开为JSON,则甚至可能导致JavaScript或其他使用JSON的客户端发生更改。因此,数据库中的简单更改可能需要更改JavaScript前端,因为您非常紧密地将图层耦合在一起。你绝对不希望在一个真实的项目中。
怎么样?你怀疑这是否实用,所以只是一个如何在(伪)代码中做到这一点的小例子:
class Repository {
public Person loadById(Long id) {
PersonEntity entity = loadEntityById(id);
Person person = new Person();
person.setId(entity.getId());
person.setName(entity.getFirstName + " " + entity.getLastName());
return person;
}
}
在此示例中,您的存储库将在内部使用实体。没有其他图层知道或使用此实体!它们是此特定图层的实现细节。因此,如果要求存储库返回一个" person",它将在该实体上工作,但它将返回一个域对象。因此,在需要更改实体的情况下,保存与repo一起使用的域层。正如您在名称的情况下所看到的,域和数据库可能不同。虽然数据库将名称存储在名字和姓氏中,但域只知道一个名称。它是如何存储名称的持久性细节。
控制器和DTO也是如此,只是另一层。