gpt4 book ai didi

domain-driven-design - 应用服务参数/返回类型

转载 作者:行者123 更新时间:2023-12-03 22:34:43 25 4
gpt4 key购买 nike

我在围绕 DDD 概念组织域的标准 Web 应用程序上工作。我想知道我的应用程序服务应该接受和返回什么样的对象。假设我有一个 User 的应用程序服务总计的。

1) DTO/简单类型(字符串、整数等)

public interface UserApplicationService {
void registerUser(UserDTO userDTO);
List<UserDTO> getUsersForOrganization(String organizationId);
}

在这种情况下,应用服务负责调用汇编程序将 DTO 转换为域对象,反之亦然。

这种方法的优点是我的应用程序服务是我的域对象的明确边界。另一个是应用服务是一个明确的事务边界。由持久化上下文管理的域对象不会泄漏到事务之外的某个地方。

缺点是在表单的情况下,验证必须基于 DTO。所以我的验证规则在域(对象负责其状态)和 DTO 验证规则之间重复。 (如 Spring MVC sample application 的情况)。此外,如果 View 的某些部分需要另一种形式的模型(假设 UserDTO 没有足够的信息来呈现 View ),我将需要创建另一个 DTO 并基于从应用程序服务返回的几个 DTO,组合另一个,被 View 使用。

2) 域名类型
public interface UserApplicationService {
void registerUser(User user);
List<User> getUsersForOrganization(OrganizationId organizationId);
}

在这种情况下, Controller /演示者负责转换。

最大的缺点是我的域对象从应用程序服务泄漏 - 没有明确的分离。另外,我们的交易边界在哪里?可能附加到的域对象,例如 Hibernate session ,泄漏到应用程序服务层之外。 (但是,我注意到这是编写了多少示例应用程序。)

优点可能是 Controller /展示器负责为 View 准备模型,因此它可以根据 View 需求组合 DTO。例如, View 可能需要一些附加信息,这些信息在 DTO 中没有从 #getUsersForOrganizationMethod 返回。此外,验证可能基于域对象,因此它不会在 DTO 和域对象之间重复。

3)领域对象+门面

这是 DDDsample application 中使用的第三个选项.应用程序服务返回域类型,但有一些 Facade 负责转换。所以在我的例子中, Controller /演示者使用 DTO 与 Facade 对话,Facade 进行转换并使用域对象与应用程序服务对话。然而,以我的拙见,这似乎有点让人不知所措——层太多,样板代码太多。对于一个应用程序服务来说,这听起来可能不错,但如果我们有几十个,我们需要有相同数量的外观方法——纯粹的重复。此外,交易边界在哪里?

最佳答案

+1

我更喜欢混合解决方案。

1) 我使用域对象作为参数,但仅限于 值对象 s。我相信的生命周期实体 s 应该小心管理,大多数时候 View 没有足够的值来填充整个 实体除了非常简单的 CRUD 应用程序。我多次看到一些开发者 init 实体通过构造函数粗心大意地只填充特定函数所需的部分字段,这使得很容易为 NullPointerException 引入错误,并且被指派解决问题的可怜人必须搜索数十种方法才能找到位置实体给定的创建。 实体 s 是从 中检索的存储库 或由 创建工厂在我的项目中。

有时为了简单起见,我使用一些表单对象作为参数。

2)我使用mvc Controller将应用服务返回的域对象转换为ViewAdapter(一个组件网将域模型与ui解耦),有时需要在这里完成分离工作。

3) 我使用 门面 仅当需要通过远程过程调用(如 Web 服务)公开应用程序服务时。 Dto 在这种情况下,s 用作参数和返回类型,而 门面 负责转换 DTO 领域模型 .

4) 如果应用程序服务需要同时暴露给 web View 和远程过程调用,验证就会很尴尬。这会导致在表单对象和 Dtos 上实现重复验证。我仅验证简单的约束(不为空,仅举几例,业务规则由域对象以编程方式验证),因为我还没有找到完美的解决方案。

希望这会有所帮助,如果有更好的解决方案,请告诉我。

更新1:

1) 我必须承认我不是这方面的大师,我也在努力寻找一个好的解决方案。所以有时我当前的解决方案中存在一些不一致的地方,例如您在评论中提到的表单 bean。有时我们将某种形式的 bean 作为 Command 并在其中放置一些域逻辑,因此这些命令在这种情况下属于域层。

2) 事务边界在应用服务上。从技术上讲,域对象可能会无意中被修改出边界。我们通过团队纪律和代码审查来涵盖这一点。

关于domain-driven-design - 应用服务参数/返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17979774/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com